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

45
在AWS Cognito中,您可以将用户添加到组中(在首先创建组之后)。一个用户可以属于一个或多个组。
使用JavaScript SDK (https://github.com/aws/amazon-cognito-identity-js),是否有一种方法来读取分配的组?是否aws-sdk可以通过amazon-cognito-identity-js提供访问权限?
8个回答

72
如果您只需要Cognito UserPools组,该用户已是其成员,而不是进行单独的API调用,那么这些数据已经编码在在认证时接收到的idToken.jwtToken中。
这对于在angular/react等应用程序中进行客户端渲染/访问决策非常有用。
请参阅此示例解码idToken.jwtToken中"cognito:groups"数组声明。
{
  "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>"
}
希望这有所帮助。

我其实发现这是事实,但从来没有更新答案。谢谢! - user1322092
1
我在解码JWT令牌时无法查看用户组,你能告诉我你是如何解码令牌的吗?@bfieber - VINEET SHARMA
我也不理解 cognito:groups。 - Marcus Christiansen
我最初也没有"cognito:groups"字段,但当我创建了一个组并将我的用户添加到其中时,"cognito:groups"字段就出现在令牌中了。 - AshleyS
小心这个解决方案。如果你不在后台检查它,可能会出现一些安全问题... - undefined

21

我最初期望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']);
        });
    }
});

非常棒的例子! - user1322092

15
如果您正在使用Amplify,且使用currentAuthenticatedUser方法,则可以使用以下代码从响应中获取组信息:
response.signInUserSession.idToken.payload['cognito:groups']

您可以使用currentSession方法中的任意一种:

response.accessToken.payload['cognito:groups']
或者
response.idToken.payload['cognito:groups']

10

这个API是存在的- AdminListGroupsForUser。你没有看到它的原因如其名称所示,该API目前仅在管理员基础上可用。Cognito SDK不包括管理员API。它将包含在AWS SDK/服务器端SDK中,但值得注意的是,此API确实需要开发人员凭据,所有管理员API都需要。


Jeff,谢谢。我正在编写一个公共的客户端JS应用程序。我认为我不能使用AWS管理SDK,因为存储凭据的机制不允许...? - user1322092
2
这是公平的。作为管理员API,您必须拥有开发者凭据,因此作为客户端应用程序,这是一个冒险的想法。我可以将此作为功能请求添加到用户级版本中! - Jeff Bailey
1
谢谢Jeff,感谢您。有很多用途。我可以轻松地使用它进行租户管理(例如SaaS应用程序),因为它能够读取组ID。 - user1322092
1
我会将此转发给上级,感谢您的建议! - Jeff Bailey

3
您无需解码任何内容,数据已经可以从 session.getIdToken().payload['cognito:groups'] 获取。

2
无法使其工作,提示session.getIdToken().payload未定义,尽管session.getIdToken()已定义为{ jwtToken:“ejkwjkwjflkwfj…” }。 - Graham Hesketh

2

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

session.getIdToken().decodePayload();

这将返回键中的组数组。


无法使其工作,它显示“session.getIdToken(...).decodePayload不是函数”。 - Graham Hesketh
你可能应该现在远离这个库,转而看看aws-amplify。 - bwobbones
远离哪个库? - Graham Hesketh
亚马逊认证身份 JavaScript 库 - bwobbones

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



0
如果您想在后端列出特定用户的组并将它们作为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]*string{true: pageNo, false: nil}[pageNo != nil])
    if err != nil {
        return nil, nil, err
    }
    return page.Groups, page.NextToken, nil
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接