AWS Cognito - SerializationException(在不期望的地方找到结构或映射的开始)

Posted

技术标签:

【中文标题】AWS Cognito - SerializationException(在不期望的地方找到结构或映射的开始)【英文标题】:AWS Cognito - SerializationException (Start of structure or map found where not expected) 【发布时间】:2018-09-30 18:24:48 【问题描述】:

我在 Cognito 用户池中创建了一个用户,使用如图所示的创建用户选项,并希望该用户在第一次登录时设置一个新密码。为此,我使用了以下给定的方法,如 AWS 文档中给出的那样 Create User from AWS

cognitouser.completeNewPasswordChallenge()

下面是我的代码

//Start: setNewPasswordForAdmin
    setNewPasswordForAdmin(username: string, password: string) 

        //Start: Creating new user with username and pool data
        const adminUserdata = 
            Username: username,
            Pool: userpoolAdmin
        
        const adminuser = new CognitoUser(adminUserdata);
        //End: Creating new user with username and pool data


        //create attributelist array which will contain all the attributes requried for signing in
        //these attributes are those attributes, which are selected while creating user pool on aws
        const attributeList : CognitoUserAttribute[] = [];

        //form a json object containing Name and Value of attribute used
        const usernameattribute = 
            Name:'username',
            Value: username
        

        //Push list of attributes in the attributeList array
        attributeList.push(new CognitoUserAttribute(usernameattribute));
        console.log(attributeList);
        const that = this;

        adminuser.completeNewPasswordChallenge(password, attributeList ,
            onFailure(err)

                console.log(err);
            ,
            onSuccess(result)
                console.log(":::::::: Password change successfull ");

                that.router.navigate(['']);
            
        );
    
    //End: setNewPasswordForAdmin

执行此操作后,我收到一条错误消息,

代码:“SerializationException”,名称:“SerializationException”, 消息:“发现结构或地图的起点不是预期的。”

这些是我在用户池中选择的属性

List Of Attributes and permissions in user pool

请帮我解决这个问题。

【问题讨论】:

【参考方案1】:

在我的情况下,它最终被发送到我的 resetPassword 助手的格式错误的数据。该函数正在寻找三个参数(usernamecodepassword):

export default function (username, code, password) 
    …

…我将它们作为对象发送:

yield call(authResetPassword, 
    code: DOMPurify.sanitize(verificationCode),
    username: DOMPurify.sanitize(email),
    password: DOMPurify.sanitize(newPassword),
)

我刚刚更新了助手,一切就绪!

export default function ( username, code, password ) 
    …

只需将您的数据记录到 setNewPasswordForAdmin 函数中,我敢打赌您会在那里发现问题。

【讨论】:

【参考方案2】:

编辑:由于 OP 的函数参数类型,除非两个参数都是字符串,否则它不会执行。他们不在我的情况下,所以问题有所不同。但是,当有人用谷歌搜索此错误消息时,会出现此页面,因此我将原始答案留在下面,以防其他人遇到与我相同的问题:

我有(编辑:几乎)同样的问题。据我所知,这种响应在各种 AWS API 上都是可能的,而且它并不特定于 Cognito,尽管我也在使用 Cognito 客户端应用程序。

当您的请求正文包含错误类型的变量时发送此响应,例如布尔而不是字符串(或者在我的情况下,对象而不是字符串)。

但是,仅知道这一点并没有帮助我。 我正在使用 Vue.js,使用 amazon-cognito-identity-js 的 CognitoUserPool.completeNewPasswordChallengeCognitoUserPool.signUp 方法发送输入元素的值。该请求在 Chrome 中看起来不错,在 Vue 开发工具中的值似乎还可以,而 Amazon 的错误消息是神秘且未记录的。

问题是我发送了输入元素节点本身而不是它们的值:variableName 而不是 this.variableName

【讨论】:

抱歉,这里不是这样。如果他试图将 html 元素作为该服务方法的参数,而该服务方法只接受字符串,则该代码将无法编译。 我相应地调整了我的回复。由于这个错误很少在互联网上讨论,而且当人们用谷歌搜索这个问题时,这个页面就会出现,我将我原来的答案留给其他人,并附加免责声明,这实际上不是 OP 的确切案例的解决方案。【参考方案3】:

我遇到了完全相同的问题,但在网上找不到比某些数据格式错误更好的答案。

由于您可能正在使用 amazon-cognito-identity-js 库并且它不再处于开发阶段,我建议您升级到具有这些功能的 aws-amplify现在包括在内并且是最新的。

要使用它,首先 npm install aws-amplify aws-sdk 然后在您的 ma​​in.ts 文件中配置您的用户池:

Amplify.configure(
  Auth: 
    region: 'eu-west-1',
    userPoolId: 'eu-west-1_fasd8734s',
    userPoolWebClientId: 'asd387dhaskj'
  
);

接下来,实现本文档中的登录方法:https://aws-amplify.github.io/docs/js/authentication#sign-in

您可以像示例中一样使用 async await,或者您可以在 cognito 服务中创建更小的方法并将它们包装在 Observables 中,如下所示:

import  from, Observable, throwError  from 'rxjs';
import  Auth  from 'aws-amplify';
import  catchError  from 'rxjs/operators';

@Injectable(
  providedIn: 'root'
)
export class CognitoService 

  public authenticate(username: string, password: string): Observable<any> 
    return from(Auth.signIn(username, password)).pipe(
      catchError(error => throwError(error))
    );
  

  public completeNewPassowrd(user: any, newPassword: string): Observable<any> 
    return from(
      Auth.completeNewPassword(
        user, // Cognito User Object
        newPassword,
        
      )
    ).pipe(catchError(error => throwError(error)));
  

  public getSession() 
    return from(Auth.currentSession()).pipe(
      catchError(error => throwError(error))
    );
  

  public getAccessToken() 
    return from(Auth.currentSession()).pipe(
      map((session: any) => 
        return session.getAccessToken();
      ),
      catchError(error => throwError(error))
    );
  


我能够通过更改为 aws-amplify 来解决问题,我希望这会有所帮助,即使它不能直接回答您的问题。

【讨论】:

这并不是对原始问题的真正答案。

以上是关于AWS Cognito - SerializationException(在不期望的地方找到结构或映射的开始)的主要内容,如果未能解决你的问题,请参考以下文章

AWS Cognito JWT 令牌验证

AWS Cognito:Cognito 用户池的元数据 URL 在哪里?

AWS Cognito 健康检查

AWS cognito 快速将令牌交换为凭证

AWS Cognito 模拟

在 AWS Cognito 中管理用户