AWS Amplify,如何检查用户是否登录?

问题描述 投票:0回答:9

我一直在使用

aws-amplify
库和 ionic,想知道如何检查用户是否登录?我有 Firebase 背景,所以这是完全不同的。这样我就可以根据用户的登录状态授予对某些页面的访问权限。在我的
auth
提供商中,我导入
Amplify {Auth}
。我可以看到可以获取几条数据,但我不知道该使用什么。有
currentUserPoolUser
getCurrentUser()
getSyncedUser()
currentAuthenticatedUser
currentSession
getCurrentUser()
userSession
currentUserCredentials
currentCredentials
currentUserInfo
。我似乎也找不到任何有关这方面的文档。我读过和看过的所有内容都会被掩盖,直到用户登录......这一切都应该在客户端上完成吗?谢谢。

amazon-web-services ionic-framework aws-sdk aws-amplify
9个回答
24
投票

我在每个页面中使用 ionViewCanEnter() 函数来允许/拒绝访问。该函数的返回值决定页面是否可以加载(并且在运行构造函数之前执行)。在这个函数中,你必须实现你的逻辑。

就我而言,使用 Amplify,我正在这样做:

async function ionViewCanEnter() {
    try {
        await Auth.currentAuthenticatedUser();
        return true;
    } catch {
        return false;
    }
}

由于 amplify currentAuthenticatedUser() 返回一个承诺,我使用异步等待来等待响应以了解用户是否已登录。


14
投票

嘿我想现在你只能使用

Auth.currentUserInfo();
来检测是否登录。如果您尚未登录,它将返回
undefined
;如果您已登录,它将返回
object


4
投票

这可以使用 Auth 的 fetchAuthSession() 方法来实现。

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

3
投票

您可以通过监听集线器将其设为自定义挂钩(上述答案中的 ionViewCanEnter 用于启动应用程序):
挂钩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();

2
投票

如果您将 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
canActivate
防护。

Angular 路由器防护:https://angular.io/guide/router#preventing-unauthorized-access


1
投票

一个与我一起工作的例子,小心流量控制,两者 事件循环风格和异步/等待风格:

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);
        }
      }
    },

0
投票
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));

此方法可用于在页面加载时检查用户是否登录。如果没有用户登录,则会抛出错误。该方法应在配置 Auth 模块或用户登录后调用。以确保您可以监听 auth 事件

configured
signIn

来源:https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#retrieve-current-authenticated-user


0
投票

我写了一个很好地满足我的目的的钩子:

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;

0
投票

我通过在 Amplify 的

Authenticator
组件中更新的全局上下文解决了这个问题。

最终结果如下所示:

import { AuthenticatedDataContext } from '../amplify/AuthenticatedDataContext';

const MyComponent = () => {
  const { data: auth } = React.useContext(AuthenticatedDataContext);
  return <>{auth.isAuthenticated ? `You are logged in as ${JSON.stringify(auth.user)}` : 'You are logged out'}</>
};

实现如下。

AuthenticatedDataContext.js

import * as React from 'react';


export const AuthenticatedDataContext = React.createContext();

const initData = () => ({
  user: undefined,
  isAuthenticated: false,
});

export const AuthenticatedData = (props) => {
  const { children } = props;
  const [cache, setCache] = React.useState({
    keys: new Set(),
    data: initData(),
  });

  const register = (key, user) => {
    return setCache((prevCache) => {
      const keys = new Set(prevCache.keys);
      keys.add(key);

      const data = {user, isAuthenticated: !!user};

      return {keys, data};
    });
  };

  const unregister = (key) => {
    return setCache((prevCache) => {
      if (prevCache.keys.has(key)) {
        const keys = new Set(prevCache.keys);
        keys.delete(key);

        const data = (keys.size === 0) ? initData() : prevCache.data;

        return {keys, data};
      } else {
        console.error(`AuthenticatedData.unregister: key of '${key}' does not exist`);
        return prevCache;
      }
    });
  };

  return (
    <AuthenticatedDataContext.Provider value={{data: cache.data, register, unregister}}>
      {children}
    </AuthenticatedDataContext.Provider>
  );
};

登录.js

import * as React from 'react';
import { Authenticator } from '@aws-amplify/ui-react';

import { AuthenticatedDataContext } from '../amplify/AuthenticatedDataContext';


const UserLifecycle = (props) => {
  const { children, componentId, user } = props;
  const authenticatedDataContext = React.useRef(
    React.useContext(AuthenticatedDataContext)
  );

  React.useEffect(() => {
    const { register, unregister } = authenticatedDataContext.current;
    register(componentId, user);
    return () => unregister(componentId);
  }, [componentId, user]);

  return children;
};

export const Login = (props) => {
  const { children } = props;
  const componentId = React.useId();

  return (
    <Authenticator>
      {({ signOut, user }) => (
        <UserLifecycle componentId={componentId} user={user}>
          {children}
        </UserLifecycle>
      )}
    </Authenticator>
  );
};

示例.js

// Use Login component anywhere you want to require authentication
// For example:

const MyPrivateComponent = () => {
  return (
    <Login>
      <>Secret stuff</>
    </Login>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.