LoginSignup
6
5

More than 5 years have passed since last update.

Cognito adminInitiateAuthのREFRESH_TOKENフローでSECRET_HASHが合致しないエラーが発生する

Last updated at Posted at 2019-03-16

現象

下記のコードで NotAuthorizedException: Unable to verify secret hash for client xxx が発生。
secretHashの生成方法は間違っていないはずなのになぜ...?と若干ハマりました。

const { username, password } = req.body
const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider()
const secretHash = crypto
  .createHmac('SHA256', ClientSecret)
  .update(username + ClientId)
  .digest('base64')

// ログイン
const data = await cognitoidentityserviceprovider
  .adminInitiateAuth({
    UserPoolId,
    ClientId,
    AuthFlow: 'ADMIN_NO_SRP_AUTH',
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
      SECRET_HASH: secretHash
    }
  })
  .promise()

// ログイン成功
const { AuthenticationResult } = data

// リフレッシュトークンを取得
// => NotAuthorizedException発生
await cognitoidentityserviceprovider
  .adminInitiateAuth({
    UserPoolId,
    ClientId,
    AuthFlow: 'REFRESH_TOKEN_AUTH',
    AuthParameters: {
      REFRESH_TOKEN: AuthenticationResult.RefreshToken,
      SECRET_HASH: secretHash
    }
  })
  .promise()

原因

結局、ログイン時のUSERNAMEはユーザーから入力されたEmail等を利用してsecretHashを作成するのですが、ログイン後はCognito User Poolsで割り振られたusername(ユニークなID)を利用しなければならないのでした。これはわかりにくい。

const jwt = require('jsonwebtoken')

const secretHash = crypto
  .createHmac('SHA256', ClientSecret)
  .update(jwt(AuthenticationResult.AccessToken).username + ClientId) // 本番環境では署名検証が必要です
  .digest('base64')
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5