【问题标题】:How to get user attributes (username, email, etc.) using cognito identity id如何使用 cognito 身份 id 获取用户属性(用户名、电子邮件等)
【发布时间】:2016-10-24 03:38:48
【问题描述】:

我有 AWS Cognito 身份池,它配置了 Cognito 用户池作为身份验证提供程序。

假设我在 Cognito 身份池中有一个身份的身份 ID(例如 us-east-1:XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX),其中该身份与 Cognito 用户池中的用户关联登录。

使用身份 ID,我如何获取链接的用户详细信息(电子邮件、电话、用户名)?

【问题讨论】:

    标签: amazon-web-services amazon-cognito


    【解决方案1】:

    您与 Cognito 联合身份服务交换以获取身份 ID 和凭据的 ID 令牌已经具有所有用户属性。您不需要额外调用任何服务。

    它是一个 JWT 令牌,您可以使用客户端上的任何库来解码这些值。您可以阅读this guide,了解有关 Cognito 用户池出售的代币的更多信息。

    或者,您也可以使用访问令牌调用GetUser API,这将返回所有用户信息。

    【讨论】:

    • 我正在授予用户调用单个 lambda 函数的权限。调用时,我可以获得 context.identity.cognito_identity_id。这就是为什么我想使用 identitiy_id 获取用户信息的原因,有没有办法获取 JWT 令牌?我可以安全地将它传递给有效载荷中的 lambda 函数吗?
    • 是的。有关如何执行此操作的说明,请参阅 this post
    • 我试过 GetUser API 但它给了我An error occurred (InvalidParameterException) when calling the GetUser operation: 1 validation error detected: Value at 'accessToken' failed to satisfy constraint: Member must satisfy regular expression pattern: [A-Za-z0-9-_=.]+
    • @gehad GetUser API 需要访问令牌而不是 idtoken,这就是原因。
    • 找到自定义属性的解决方案需要在应用程序设置中将它们标记为可读,然后它们将被放置在声明中
    【解决方案2】:

    使用 REST API

    访问令牌

    认为这可能对某人非常有帮助,因为我花了很多时间试图弄清楚如何仅使用 accessTokenregion 获得 UserAttributes(类似于 this 但使用 REST API (不使用 aws-sdk)

    您可以使用此 HTTP 请求获取 UserAttributesaccessToken。 (GetUser)

    Method: POST
    Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
    Content-Type: application/x-amz-json-1.1
    Content-Length: 1162 // Access Token bytes length
    X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
    Body: {"AccessToken":"ACCESS_TOKEN"}
    

    如果accessToken 有效,您应该会收到如下示例响应

    {
        "UserAttributes": [
            {
                "Name": "sub",
                "Value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
            },
            {
                "Name": "email_verified",
                "Value": "true"
            },
            {
                "Name": "name",
                "Value": "Jason"
            },
            {
                "Name": "phone_number_verified",
                "Value": "true"
            },
            {
                "Name": "phone_number",
                "Value": "+xxxxxxxxxxx"
            },
            {
                "Name": "email",
                "Value": "xxxx@gmail.com"
            }
        ],
        "Username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
    }
    

    【讨论】:

    • 我无法表达这对我有多大帮助!
    • 谢谢!这比 AWS 的可怕文档更棒!但是当我使用所有参数向https://cognito-idp.{REGION}.amazonaws.com/ 射击时,它给了我"__type": "SerializationException" 我们不是每个人都需要发布到我们自己的URL 端点吗?我们究竟从哪里得到没有在任何文档中指定的服务器 URL!
    • 对不起,它实际上是在使用那个目标 URL,只是 AccessToken 必须在正文中指定,而不是在标题中,我把它作为 auth-header... 非常感谢!尽管由于 aws-lib 的 get 用户有问题,这看起来像是一个 hack,但它拯救了我的一天!
    • 虽然这比亚马逊文档好.. 但我仍然收到此错误 - 访问令牌没有必需的范围
    • @KunalValecha 确保您使用的是“访问”令牌,而不是“id”或“刷新”令牌。我怀疑你的令牌的范围是别的东西。您可以转到jwt 调试器部分来测试您的令牌。请注意,令牌是凭据。
    【解决方案3】:

    AWS cognito-idp list-users 有一个过滤选项,允许您根据属性进行过滤。 'sub' 是与您描述的身份 id 匹配的属性。

    例如在命令行:

    aws cognito-idp list-users --user-pool-id us-east-1_abcdFghjI --filter "sub=\":XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX\""
    

    这还需要用户池 ID,我怀疑你有。此外,我不知道这是如何实现的,也不知道在过滤大量用户时它的性能如何,但我认为自定义属性在过滤器中不可用,这暗示着幕后有某种形式的索引。

    【讨论】:

    • 'sub' 不再匹配身份 ID。虽然两者的格式相似,但值不同。
    【解决方案4】:

    我遇到了类似的问题,经过太多的抓挠,我无法找到提取细节的确切方法。我的用例是在 android APP 中获取详细信息。 在查看了他们的 AWSMobile 客户端 API 代码之后。我在下面找到了它,它对我有用。

    Log.i(TAG, "用户详细信息"+ AWSMobileClient.getInstance().getUserAttributes().toString());

    推荐 - 如果您将其用于 Android 开发,请尝试使用 AWSMobileclient,因为这是推荐用于开发的新库。

    【讨论】:

      【解决方案5】:

      只是为此苦苦挣扎了一段时间,我使用Java API获取用户名的方式是:

      identityManager.login(this, new DefaultSignInResultHandler() {
              @Override
              public void onSuccess(Activity activity, IdentityProvider identityProvider) {
                  ...               
                  String userName = ((CognitoUserPoolsSignInProvider) identityProvider).getCognitoUserPool().getCurrentUser().getUserId();
      

      【讨论】:

      • 这非常适合获取 ID。但是您可以使用 getCurrentUser() 来查找电子邮件属性而不是 ID 吗?
      【解决方案6】:

      我们可以初始化一个监听器,它将监听我们的身份验证状态的变化,并允许我们访问发生的身份验证事件的类型并根据该数据更新应用程序状态。

      使用 Amplify,Hub 模块让我们可以很容易地做到这一点:

      import { Hub } from 'aws-amplify';
      
      Hub.listen('auth', (data) => {
          const {payload} = data;
          if (payload.event === 'signOut') {
             console.log('signOut');
          } else if (payload.event === 'signIn') {
             console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
          }
      });
      

      【讨论】:

        【解决方案7】:

        对于那些正在寻找如何以编程方式在 Java 中获取电子邮件参数值的人

        我假设您已经弄清楚如何从池中获取所需的/所有用户。

        假设我的所有用户都有ListUsersResult,并说我想检查第一个用户的电子邮件值:

        ListUsersResult allUsers = getAllUsers();
        UserType userType = allUsers.getUsers().get(0);
        
        

        首先我可以获取用户的所有属性:

        List<AttributeType> attributes = userType.getAttributes();
        
        

        然后循环查找我们感兴趣的属性(我们的案例email):

        for (AttributeType att : attributes) {
              if (att.getName().equals("email")) {
                // do whatever you want
        
        
              }
            }
        
        

        请记住,打印到控制台很可能不起作用,因为它是敏感数据。但是你可以这样比较:

        att.getValue().equals("mymail@mail")

        【讨论】:

          【解决方案8】:

          使用这段代码

                 GetDetailsHandler detailsHandler = new GetDetailsHandler() {
               @Override
               public void onSuccess(CognitoUserDetails cognitoUserDetails) {
                  CognitoUserAttributes cognitoUserAttributes=cognitoUserDetails.getAttributes();
                  stringStringHashMap=new HashMap<>();
                  stringStringHashMap =cognitoUserAttributes.getAttributes();
                   userNumber=stringStringHashMap.get("phone_number");
                  e1.setText(userNumber);
          
                  Log.d("Response"," Inside DEATILS HANDLER");
                  // Store details in the AppHandler
                  AppHelper.setUserDetails(cognitoUserDetails);
                  // Trusted devices?
                  handleTrustedDevice();
                 // e1.setText(input.getText().toString());
                   }
          
                   @Override
                    public void onFailure(Exception exception) {
                  closeWaitDialog();
                  showDialogMessage("Could not fetch user details!", AppHelper.formatException(exception), true);
                  }
                 };
               private void getDetails() {
              AppHelper.getPool().getUser(username).getDetailsInBackground(detailsHandler);
                }  
          

          【讨论】:

          • 你不能只用一种未指定的语言粘贴无法解释的代码并期望它会有所帮助。
          【解决方案9】:
          console.log('username is ' + cognitoUser.getUsername());
          

          【讨论】:

          • 您想通过一些解释如何解决 OPs 问题来扩充您的纯代码答案吗?
          猜你喜欢
          • 2021-09-10
          • 1970-01-01
          • 2019-06-25
          • 1970-01-01
          • 2017-08-15
          • 2020-04-21
          • 2022-12-05
          • 1970-01-01
          • 2019-05-01
          相关资源
          最近更新 更多