AWS Amplify, как проверить, вошел ли пользователь в систему?

Я использую aws-amplify библиотека с ionic и было интересно, как я могу проверить, если пользователь вошел в систему? Я исхожу из прошлого, так что это совсем другое. Это сделано для того, чтобы я мог предоставить доступ к определенным страницам в зависимости от статуса входа пользователя. В моем auth провайдер импортирую Amplify {Auth}, Я вижу, что можно получить несколько частей данных, но я не уверен, что использовать. Там в currentUserPoolUser, getCurrentUser(), getSyncedUser(), currentAuthenticatedUser, currentSession, getCurrentUser(), userSession, currentUserCredentials, currentCredentials а также currentUserInfo, Я не могу найти документацию по этому вопросу либо. Все, что я читал и смотрел, скрывается, пока пользователь не войдет в систему... Это все должно быть сделано на клиенте? Благодарю.

8 ответов

Я использую функцию ionViewCanEnter() на каждой странице, чтобы разрешить / запретить доступ. Возвращаемое значение этой функции определяет, может ли страница быть загружена или нет (и она выполняется перед запуском конструктора). Внутри этой функции вы должны реализовать свою логику.

В моем случае, используя Amplify, я делаю это:

 async ionViewCanEnter(){
    return await Auth.currentAuthenticatedUser()
      .then(() => { return true; })
      .catch(() => { return false; });
  }

Так как ampify currentAuthenticatedUser() возвращает обещание, я использую async, ожидаю ответа, чтобы узнать, вошел ли пользователь в систему или нет.

Эй, я думаю, что сейчас вы можете использовать только Auth.currentUserInfo(); определить, вошел ли в систему или нет. Он вернется undefined если вы не вошли в систему или object если ты.

Это может быть достигнуто с помощью метода Auth fetchAuthSession().

      final CognitoAuthSession res = await Amplify.Auth.fetchAuthSession();
if (res.isSignedIn) {
  // do your thang
}

Вы можете сделать его настраиваемым хуком, прослушивая хаб (ionViewCanEnter из приведенных выше ответов предназначен для загрузки приложения):
Hook tsx:

      import {useState, useEffect} from 'react';
import {Hub, Auth} from 'aws-amplify';

export default function AuthenticatedStatus(): Boolean {
  const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);

  async function ionViewCanEnter() {
    console.log('hey');
    try {
      const authenticatedUser = await Auth.currentAuthenticatedUser();
      if (authenticatedUser !== undefined) {
        setIsAuthenticated(true);
      } else {
        setIsAuthenticated(false);
      }
    } catch {
      setIsAuthenticated(false);
    }
  }

  useEffect(() => {
    ionViewCanEnter();
  });

  useEffect(() => {
    const listener = data => {
      switch (data.payload.event) {
        case 'signIn' || 'autoSignIn' || 'tokenRefresh':
          console.log('is authenticated');
          setIsAuthenticated(true);
          break;
        case 'signOut' || 'signIn_failure' || 'tokenRefresh_failure' || 'autoSignIn_failure':
          console.log('is not authenticated');
          setIsAuthenticated(false);
          break;
      }
    };

    Hub.listen('auth', listener);
  });

  return isAuthenticated;
}

как использовать:

      const isAuthenticated = AuthenticatedStatus();

Если вы используете angular с ionic, вы можете сделать что-то подобное в своей службе аутентификации

import {AmplifyService} from 'aws-amplify-angular';
.
.
  constructor(private amplifyService:AmplifyService)
  {
    this.amplifyService.authStateChange$.subscribe(auth => {
      switch (auth.state) {
        case 'signedIn':
          this.signedIn=true;
        case 'signedOut':
          this.signedIn=false;
          break;
        default:
          this.signedIn=false;
      }
    }
}

тогда вы можете использовать this.signedIn в вашем роутере с canActiavate охранник.

угловая защита маршрутизатора: https://angular.io/guide/router#preventing-unauthorized-access

Пример, который работал со мной, осторожный для управления потоком, как в стиле цикла событий, так и в стиле асинхронного/ожидания:

      import { Auth } from "aws-amplify";

...

    exampleIsLoggedIn() {
      const notLoggedInStringThrown = "The user is not authenticated";
      Auth.currentAuthenticatedUser().then(
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        (_currentAuthenticatedUser) => {
          this.$log.debug("Yes, user is logged in.");
        },
        (error) => {
          if (error === notLoggedInStringThrown) {
            this.$log.debug("No, user is not yet logged in.");
          } else {
            this.$log.error(error);
          }
        }
      );
    },
    async exampleIsLoggedInAsync() {
      const notLoggedInStringThrown = "The user is not authenticated";
      try {
        /* currentAuthenticatedUser = */ await Auth.currentAuthenticatedUser();
        this.$log.debug("Yes, user is logged in.");
      } catch (error) {
        if (error === notLoggedInStringThrown) {
          this.$log.debug("No, user is not yet logged in.");
        } else {
          this.$log.error(error);
        }
      }
    },

Я написал крючок, который хорошо служит моим целям:

      import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { Auth, Hub } from "aws-amplify";


export interface UserDetailsT {
    username: string,
    email: string,
    emailVerified: boolean,
};


const useAuth = (): [UserDetailsT | null, Dispatch<SetStateAction<UserDetailsT | null>>] => {
    const [userDetails, setUserDetails] = useState<UserDetailsT | null>(null);
    
    useEffect(() => {
        const getUserDetails = async () => {
            try {
                if (userDetails === null) {
                    const { username, attributes } = await Auth.currentAuthenticatedUser() || null;
                    setUserDetails({
                        username,
                        email: attributes?.email,
                        emailVerified: attributes?.email_verified
                    });
                }
            } catch {
                setUserDetails(null);
            }
        }

        getUserDetails();
        Hub.listen('auth', () => getUserDetails());

    }, [Auth, userDetails, setUserDetails]);

    return [userDetails, setUserDetails];
};


export default useAuth;
      import { Auth } from 'aws-amplify';

Auth.currentAuthenticatedUser({
  // Optional, By default is false. If set to true, 
  // this call will send a request to Cognito to get the latest user data
  bypassCache: false
})
  .then((user) => console.log(user))
  .catch((err) => console.log(err));

Этот метод можно использовать для проверки того, вошел ли пользователь в систему при загрузке страницы. Он выдаст ошибку, если пользователь не войдет в систему. Этот метод следует вызывать после настройки модуля аутентификации или входа пользователя в систему. Чтобы убедиться, что вы можете прослушивать события аутентификацииconfiguredилиsignIn.

Источник: https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#retrieve-current-authenticated-user

Другие вопросы по тегам