如何访问 Cognito 用户帐户的群组?

How do I access the group for a Cognito User account?

在 AWS Cognito 中,您可以将用户添加到组中(在首先创建组之后)。一个用户可能属于一个或多个组。

使用 JavaScript SDK (https://github.com/aws/amazon-cognito-identity-js),有没有办法读取分配的组? aws-sdk 会提供对 amazon-cognito-identity-js 的访问吗?

这个 API 确实存在 - AdminListGroupsForUser。顾名思义,您看不到它的原因是 API 当前仅在管理员基础上可用。 Cognito 不在移动 SDK 中包含管理员 API。它将包含在 AWS SDKs/server 端 SDK 中,但值得注意的是,这个 API 确实需要开发人员凭据,所有管理员 APIs 也是如此。

如果您只需要经过身份验证的用户所属的 Cognito UserPools 组,而不是进行单独的 API 调用,该数据将编码在您在身份验证时收到的 idToken.jwtToken 中。

这对 angular/react/etc 中的客户端 rendering/access 决策很有用。应用程序。

请参阅此示例中的 "cognito:groups" 数组声明已解码 idToken.jwtToken:

{
  "sub": "a18626f5-a011-454a-b4c2-6969b3155c24",
  "cognito:groups": [
    "uw-app-administrator",
    "uw-app-user"
  ],
  "email_verified": true,
  "iss": "https://cognito-idp.<region>.amazonaws.com/<user-pool-id>",
  "cognito:username": "<my-user-name>",
  "given_name": "<my-first-name>",
  "aud": "<audience-code>",
  "token_use": "id",
  "auth_time": 1493918449,
  "nickname": "Bubbles",
  "exp": 1493922049,
  "iat": 1493918449,
  "email": "<my-email>"
}

希望对您有所帮助。

我原本希望 Cognito JavaScript API 提供一个简单的 属性 或方法 return 组列表,但我得出的结论是它被埋没了在令牌中,因此必须了解 jwt。建立 Cognito 用户并检索会话后,组数组在 IdToken 中可用。

var jwtDecode = require('jwt-decode');
var AmazonCognitoIdentity = require('amazon-cognito-identity-js');
var CognitoUserPool = AmazonCognitoIdentity.CognitoUserPool;
var CognitoUser = AmazonCognitoIdentity.CognitoUser;

var userPool = new CognitoUserPool({UserPoolId:'', ClientId:''");
...
app.get('/app', function(req, res){
    var cognitoUser = userPool.getCurrentUser();
    if(cognitoUser != null){
        cognitoUser.getSession(function(err, session) {
            if (err) {
                console.error(err);
                return;
            }
            console.log('session validity: ' + session.isValid());

            var sessionIdInfo = jwtDecode(session.getIdToken().jwtToken);
            console.log(sessionIdInfo['cognito:groups']);
        });
    }
});

您现在可以轻松地从用户会话中获取用户组:

session.getIdToken().decodePayload();

这包含返回的 cognito:groups 键中的组数组

你不需要解码任何东西,数据已经可以从session.getIdToken().payload['cognito:groups']

获得

如果您使用 Amplify,如果您使用 currentAuthenticatedUser 方法,您可以使用以下方法从响应中获取组:

response.signInUserSession.idToken.payload['cognito:groups']

或使用 currentSession 方法,您可以使用以下任一方法:

response.accessToken.payload['cognito:groups']

response.idToken.payload['cognito:groups']

如果您打算在后端列出特定用户的组,并将它们 return 作为 API,这里是一个使用 golang 的 aws sdk 的完整示例:

func sessionWithRegion(region *string) *session.Session {
    sess := Session.Copy()
    if v := aws.StringValue(sess.Config.Region); len(v) == 0 {
        sess.Config.Region = region
    }

    return sess
}

func getGroupsForUser(region, userPoolId, userName *string, limit int64, nextToken ...*string) (*cognitoidentityprovider.AdminListGroupsForUserOutput, error) {
    sess := sessionWithRegion(region)
    svc := cognitoidentityprovider.New(sess)

    input := &cognitoidentityprovider.AdminListGroupsForUserInput{
        UserPoolId: userPoolId,
        Username:   userName,
        Limit:      &limit,
    }

    if nextToken != nil && len(nextToken) > 0 {
        input.NextToken = nextToken[0]
    }

    return svc.AdminListGroupsForUser(input)

}

nextToken用于支持分页加载更多的组,以防我们还有用户从cognitoreturn到return/fetch,换句话说就是抓取下一页。这是一个简单的例子,说明你的电话应该是什么样子

func listGroups(pageNo *string) ([]*cognitoidentityprovider.GroupType, *string, error) {

    page, err := getGroupsForUser(aws.String("us-east-1"), aws.String("xxx"), aws.String("myuserName"), 60, map[bool]*string{true: pageNo, false: nil}[pageNo != nil])
    if err != nil {
        return nil, nil, err
    }
    return page.Groups, page.NextToken, nil
}

以上代码片段只是为了让您和社区的其他同事更容易理解这个想法以及如何实现它,但它可能需要一些调整。如果您需要更多帮助,请随时发表评论。

如果您正在使用 Amplify 和 Auth 模块,您可以调用 currentAuthenticatedUser 方法,并拉取有效负载信息。见下文:

import {API, Auth} from "aws-amplify";


export const getCurrentUser = async () => {
  try {
    const userInfo = await Auth.currentAuthenticatedUser({bypassCache:true})
    console.log("User info: ",userInfo)

    if(userInfo){
// returns a Array<strings>
      return userInfo.signInUserSession.idToken.payload["cognito:groups"];
    }
  }

  catch (err) {
    console.log('error: ', err)
  }
}