[英]Passwordless authentication flow using Cognito & API Gateway & Lambda (Python)
I've been trying to implement passwordless authentication using AWS Cognito & API Gateway & Lambda (Python)我一直在尝试使用 AWS Cognito & API Gateway & Lambda (Python) 实现无密码身份验证
I have followed these articles: https://medium.com/digicred/password-less-authentication-in-cognito-cafa016d4db7 https://medium.com/@pjatocheseminario/passwordless-api-using-cognito-and-serverless-framework-7fa952191352我关注了这些文章: https : //medium.com/digicred/password-less-authentication-in-cognito-cafa016d4db7 https://medium.com/@pjatocheseminario/passwordless-api-using-cognito-and-serverless-框架-7fa952191352
I have configured Cognito (to accept CUSTOM_AUTH), added the Lambdas, and created the API endpoints:我已经配置了 Cognito(接受 CUSTOM_AUTH),添加了 Lambda,并创建了 API 端点:
/sign-up
/initiate-auth (aka initiate login)
/respond-to-auth-challenge (aka (verify login)
When calling initiateAuth I receive the following response: An error occurred (NotAuthorizedException) when calling the InitiateAuth operation: Incorrect username or password."调用initiateAuth 时,我收到以下响应:调用InitiateAuth 操作时发生错误(NotAuthorizedException):用户名或密码不正确。”
I'm using CUSTOM_AUTH which doesn't require password, and the user name is definitely correct because it actually initiates the authentication flow and I receive a code, however because boto3 doesn't respond with a session I can't continue the authentication.我正在使用不需要密码的 CUSTOM_AUTH,并且用户名绝对正确,因为它实际上启动了身份验证流程并且我收到了一个代码,但是因为 boto3 不响应会话,我无法继续身份验证。
This is how I call Cognito:这就是我调用 Cognito 的方式:
res = cognito.initiate_auth(
ClientId=client_id,
AuthFlow="CUSTOM_AUTH",
AuthParameters={
"USERNAME": email,
"PASSWORD": random_password
}
)
It's probably something small I'm missing but I can't figure out what.这可能是我遗漏的一些小东西,但我不知道是什么。
Your client code looks OK, mine has ClientId
param in it but if your code is not raising an exception then it should be fine.您的客户端代码看起来不错,我的客户端代码中有ClientId
参数,但如果您的代码没有引发异常,那么应该没问题。 Unless you had Generate client secret
option checked when you created your app client.除非您在创建应用程序客户端时选中了Generate client secret
选项。 If that is the case then you have to pass in SECRET_HASH
in AuthParameters
like the following:如果是这样的话,那么你必须在通过SECRET_HASH
在AuthParameters
像下面这样:
import hmac
import hashlib
import base64
def get_secret_hash(email, client_id, client_secret):
"""
A keyed-hash message authentication code (HMAC) calculated using
the secret key of a user pool client and username plus the client
ID in the message.
"""
message = email + client_id
client_secret = str.encode(client_secret)
dig = hmac.new(client_secret, msg=message.encode('UTF-8'), digestmod=hashlib.sha256).digest()
return base64.b64encode(dig).decode()
client.admin_initiate_auth(
UserPoolId=COGNITO_USER_POOL_ID,
ClientId=CLIENT_ID,
AuthFlow='CUSTOM_AUTH',
AuthParameters={
'USERNAME': email,
'SECRET_HASH': get_secret_hash(email, CLIENT_ID, CLIENT_SECRET) # Omit if secret key option is disabled.
},
)
Next, double check the following:接下来,仔细检查以下内容:
Under App clients > * > Auth Flows Configuration
, is ALLOW_CUSTOM_AUTH
option enabled for your client?在App clients > * > Auth Flows Configuration
,是否为您的客户端启用了ALLOW_CUSTOM_AUTH
选项?
Under App integration > App client settings > * > Enabled Identity Providers
, is your user pool selected?在App integration > App client settings > * > Enabled Identity Providers
,是否选择了您的用户池?
If you have Cognito setup correctly and your code still doesn't work then it is probably the lambda code.如果您正确设置了 Cognito 并且您的代码仍然无法工作,那么它可能是 lambda 代码。 You probably know this but for password-less custom auth you need to use 3 lambda triggers: Define Auth Challenge
, Create Auth Challenge
, and Verify Auth Challenge
.您可能知道这一点,但对于无密码自定义身份验证,您需要使用 3 个 lambda 触发器: Define Auth Challenge
身份Define Auth Challenge
、 Create Auth Challenge
身份Create Auth Challenge
和Verify Auth Challenge
身份Verify Auth Challenge
。
Custom auth lambdas events are triggered in the following order:自定义 auth lambdas 事件按以下顺序触发:
def lambda_handler(event, context):
if event['triggerSource'] == 'DefineAuthChallenge_Authentication':
event['response']['challengeName'] = 'CUSTOM_CHALLENGE'
event['response']['issueTokens'] = False
event['response']['failAuthentication'] = False
if event['request']['session']: # Needed for step 4.
# If all of the challenges are answered, issue tokens.
event['response']['issueTokens'] = all(
answered_challenge['challengeResult'] for answered_challenge in event['request']['session'])
return event
def lambda_handler(event, context):
if event['triggerSource'] == 'CreateAuthChallenge_Authentication':
if event['request']['challengeName'] == 'CUSTOM_CHALLENGE':
event['response']['privateChallengeParameters'] = {}
event['response']['privateChallengeParameters']['answer'] = 'YOUR CHALLENGE ANSWER HERE'
event['response']['challengeMetadata'] = 'AUTHENTICATE_AS_CHALLENGE'
return event
Then your client must respond to the challenge:然后您的客户必须应对挑战:
client.respond_to_auth_challenge(
ClientId=CLIENT_ID,
ChallengeName='CUSTOM_CHALLENGE',
Session=session,
ChallengeResponses={
'USERNAME': email,
'ANSWER': 'Extra Protection!',
'SECRET_HASH': get_secret_hash(email, CLIENT_ID, CLIENT_SECRET) # Omit if secret key option is disabled.
}
)
def lambda_handler(event, context):
if event['triggerSource'] == 'VerifyAuthChallengeResponse_Authentication':
if event['request']['challengeAnswer'] == event['request']['privateChallengeParameters']['answer']:
event['response']['answerCorrect'] = True
return event
event['response']['issueTokens']
to True
to return tokens (code shown in step 1), or issue another challenge to keep repeating steps 1-3.将event['response']['issueTokens']
为True
以返回令牌(步骤 1 中显示的代码),或发出另一个质询以继续重复步骤 1-3。 Finally, make sure that if case-insensitivity option is enabled for your user pool too.最后,请确保是否也为您的用户池启用了不区分大小写选项。 Also, I can't exactly recall if CUSTOM_AUTH
flow worked if the user is in FORCE_CHANGE_PASSWORD
status.另外,如果用户处于FORCE_CHANGE_PASSWORD
状态,我无法完全回忆CUSTOM_AUTH
流程是否FORCE_CHANGE_PASSWORD
。 If the user is in that state, then try settings a permanent password with the sdk to set the status to CONFIRMED
.如果用户处于该状态,则尝试使用 sdk 设置永久密码以将状态设置为CONFIRMED
。
I was facing the same error, and I think that the error message is misleading.我遇到了同样的错误,我认为错误消息具有误导性。 When you did not respond correctly in Create-Auth-Challenge lambda, you will get this error.当您在 Create-Auth-Challenge lambda 中没有正确响应时,您将收到此错误。 So make sure everything is right in your lambda.因此,请确保您的 lambda 中一切正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.