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

Posted

技术标签:

【中文标题】如何访问 Cognito 用户帐户的组?【英文标题】:How do I access the group for a Cognito User account? 【发布时间】:2017-06-09 06:17:19 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

这对于 angular/react/etc 中的客户端渲染/访问决策很有用。应用程序。

请参阅本示例中的“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>"

希望这会有所帮助。

【讨论】:

我实际上发现是这种情况,但从不去更新答案。谢谢! 解码 JWT 令牌时无法查看用户组,您能告诉我您是如何解码令牌的吗? @bfieber 我也不知道 cognito:groups 我最初也没有“cognito:groups”字段,但是当我创建一个组然后将我的用户添加到其中时,“cognito:groups”字段随后出现在令牌中。 【参考方案2】:

我最初希望 Cognito JavaScript API 提供一个简单的属性或方法来返回组列表,但我得出的结论是它隐藏在一个令牌中,因此必须了解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']);
        );
    
);

【讨论】:

非常好的例子!【参考方案3】:

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

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

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

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

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

【讨论】:

【参考方案4】:

此 API 确实存在 - AdminListGroupsForUser。顾名思义,您没有看到它的原因是,该 API 目前仅在管理员基础上可用。 Cognito 在移动 SDK 中不包含管理 API。它将包含在 AWS 开发工具包/服务器端开发工具包中,但值得注意的是,此 API 和所有管理 API 一样需要开发人员凭证。

【讨论】:

杰夫,谢谢。我正在编写一个公共的客户端 JS 应用程序。我假设我将无法使用 AWS admin SDK,因为存储凭证的机制......? 这很公平。作为管理员 API,您必须拥有开发人员的信誉,因此作为客户端应用程序,这是一个冒险的想法。不过,我可以将此作为添加用户级别版本的功能请求! 谢谢杰夫,感激不尽。许多用例。凭借读取组 ID 的能力,我可以轻松地将其用于租赁(例如 SaaS 应用程序)。 我会转发给上级的,谢谢建议!【参考方案5】:

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

【讨论】:

不能让它工作,说 session.getIdToken().payload 是未定义的,即使 session.getIdToken() 被定义为 jwtToken:"ejkwjkwjflkwfj..." 【参考方案6】:

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

session.getIdToken().decodePayload();

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

【讨论】:

无法让它工作,它说“session.getIdToken(...).decodePayload 不是一个函数” 也许你现在应该离开这个库,看看 aws-amplify 离开什么图书馆? amazon-cognito-identity-js【参考方案7】:

如果您要在后端列出特定用户的组并将它们作为 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 用于支持分页加载更多组,以防我们仍然有用户从 cognito 返回返回/获取,换句话说,就是获取下一页。这是一个简单的例子,说明你的调用应该是什么样子的

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]*stringtrue: pageNo, false: nil[pageNo != nil])
    if err != nil 
        return nil, nil, err
    
    return page.Groups, page.NextToken, nil

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

【讨论】:

【参考方案8】:

如果您正在使用 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)
  



【讨论】:

以上是关于如何访问 Cognito 用户帐户的组?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core AWS Cognito JWT

AWS Cognito - 使用 JWT 与 cognito.getUser 开发工具包验证令牌

如何将数据从Cognito Sync保存到服务器

无需登录即可访问api-gateway,然后创建帐户并进行授权

在 Cognito 中链接第三方应用程序帐户

Cognito 用户池:如何使用刷新令牌刷新访问令牌