I created a Cognito User Pool where users can sign up but can no longer sign in. I have attempted many different configurations, such as disabling MFA, turning off remembering of devices as I saw that can cause this issue, to no avail.
The weirdest thing is, that is works fine locally (localhost:5000
). I can create accounts and login without any drama, but when I try to login on my site https://example.com
(hosted on S3) it throws the above error. The users actually seem to get created in Cognito too if I signup - so that works, but the logins just don't work anywhere but locally.
I have double, triple checked every setting, env variable, recreated the user pool etc.
Error
This is the ambiguous error thrown when I attempt to login:
{
__type: "NotAuthorizedException",
message: "Incorrect username or password."
}
Pre-signup triggered lambda
I am confirming the users before they sign up via lambda:
import {INTERNAL_SERVER_ERROR} from 'http-status-codes';
export async function validateHumanViaSns(
event: CognitoUserPoolTriggerEvent,
context: Context,
callback: Callback
): Promise<CognitoUserPoolTriggerHandler> {
try {
event.response.autoConfirmUser = true;
callback(null, event);
return;
} catch (error) {
console.error(error);
callback(null, new Response(INTERNAL_SERVER_ERROR, {message: 'Something went wrong'}));
return;
}
}
package.json
My client is using the latest amplify-js library.
dependencies: {
"amplify": "1.1.19" // broken since 1.1.18
}
CloudFormation Cognito template
UserPool:
Type: 'AWS::Cognito::UserPool'
Properties:
UserPoolName: myapp-${self:provider.stage}-user-pool
SmsVerificationMessage: 'Your verification code is {####}.'
AutoVerifiedAttributes:
- email
MfaConfiguration: 'OFF'
EmailVerificationSubject: 'Your MyApp verification code'
EmailVerificationMessage: 'Your MyApp verification code is {####}.'
SmsAuthenticationMessage: 'Your MyApp authentication code is {####}.'
Schema:
- Name: name
AttributeDataType: String
Mutable: true
Required: false
- Name: email
AttributeDataType: String
Mutable: false
Required: false
- Name: phone_number
AttributeDataType: String
Mutable: true
Required: false
Policies:
PasswordPolicy:
RequireLowercase: true
RequireSymbols: false
RequireNumbers: true
MinimumLength: 8
RequireUppercase: true
AdminCreateUserConfig:
InviteMessageTemplate:
EmailMessage: 'Your MyApp username is {username} and temporary password is {####}.'
EmailSubject: 'Your temporary MyApp password'
SMSMessage: 'Your MyApp username is {username} and temporary password is {####}.'
UnusedAccountValidityDays: 7
AllowAdminCreateUserOnly: false
# Creates a User Pool Client to be used by the identity pool
UserPoolClient:
Type: 'AWS::Cognito::UserPoolClient'
Properties:
ClientName: myapp-${self:provider.stage}-web-client
GenerateSecret: false
UserPoolId:
Ref: UserPool
# Creates a federeated Identity pool
IdentityPool:
Type: 'AWS::Cognito::IdentityPool'
Properties:
IdentityPoolName: MyApp{self:provider.stage}Identity
AllowUnauthenticatedIdentities: true
CognitoIdentityProviders:
- ClientId:
Ref: UserPoolClient
ProviderName:
'Fn::GetAtt': [ UserPool, ProviderName ]
# Create a role for unauthorized access to AWS resources. Very limited access. Only allows users in the previously created Identity Pool
CognitoUnAuthorizedRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Principal:
Federated: 'cognito-identity.amazonaws.com '
Action:
- 'sts:AssumeRoleWithWebIdentity'
Condition:
StringEquals:
'cognito-identity.amazonaws.com :aud':
Ref: IdentityPool
'ForAnyValue:StringLike':
'cognito-identity.amazonaws.com :amr': unauthenticated
Policies:
- PolicyName: 'CognitoUnauthorizedPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action:
- 'mobileanalytics:PutEvents'
- 'cognito-sync:*'
Resource: '*'
# Create a role for authorized access to AWS resources. Control what your user can access. This example only allows Lambda invokation
# Only allows users in the previously created Identity Pool
CognitoAuthorizedRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Principal:
Federated: 'cognito-identity.amazonaws.com '
Action:
- 'sts:AssumeRoleWithWebIdentity'
Condition:
StringEquals:
'cognito-identity.amazonaws.com :aud':
Ref: IdentityPool
'ForAnyValue:StringLike':
'cognito-identity.amazonaws.com :amr': authenticated
Policies:
- PolicyName: 'CognitoAuthorizedPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action:
- 'mobileanalytics:PutEvents'
- 'cognito-sync:*'
- 'cognito-identity:*'
Resource: '*'
- Effect: 'Allow'
Action:
- 'lambda:InvokeFunction'
Resource: '*'
# Assigns the roles to the Identity Pool
IdentityPoolRoleMapping:
Type: 'AWS::Cognito::IdentityPoolRoleAttachment'
Properties:
IdentityPoolId:
Ref: IdentityPool
Roles:
authenticated:
'Fn::GetAtt': [ CognitoAuthorizedRole, Arn ]
unauthenticated:
'Fn::GetAtt': [ CognitoUnAuthorizedRole, Arn ]
Does anyone have any ideas as to why this particular error is thrown (I think it's misleading) or even better, how to fix this?
This was fixed over in the AWS Amplify Github issue backlog, more context here.
Wherever you import amplify, you need to import a crypto-js
dependency directly beforehand, due to Typescript compilation issue in the amplify-js library:
import 'crypto-js/lib-typedarrays'; // add this line
import Amplify, {Auth} from 'aws-amplify';
It looks like this will be a permanent fix in a future pull request, so depending on when you land here, try updating the aws-amplify
package to something > 1.1.19
first, to see if it's been fixed in the main package first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With