Using Cognito to authorize users
Setup Cognito in serverless
Firstly, you have to add Cognito User Pool and User Pool Client resources to the serverless file:
CognitoUserPool: | |
Type: AWS::Cognito::UserPool | |
Properties: | |
UserPoolName: ${self:custom.CognitoUserPoolName} | |
Policies: | |
PasswordPolicy: | |
RequireLowercase: true | |
RequireSymbols: false | |
RequireUppercase: false | |
MinimumLength: 6 | |
CognitoUserPoolClient: | |
Type: AWS::Cognito::UserPoolClient | |
Properties: | |
ClientName: user-pool-client | |
UserPoolId: | |
Ref: CognitoUserPool | |
ExplicitAuthFlows: | |
- ADMIN_NO_SRP_AUTH | |
GenerateSecret: false |
For convenience, we will declare a custom variable at the top level of the serverless file:
custom: | |
CognitoUserPoolName: user-pool # Name for your cognito user pool |
If you want to autoconfirm users who sign up, you need to add preSignUp function to your lambda functions list:
preSignUp: | |
handler: handler.preSignUp | |
events: | |
- cognitoUserPool: | |
pool: ${self:custom.CognitoUserPoolName} | |
trigger: PreSignUp | |
existing: true |
And write the following handler for this function
module.exports.preSignUp = async (event, context, callback) => { | |
// Confirm the user | |
event.response.autoConfirmUser = true; | |
// Return to Amazon Cognito | |
callback(null, event); | |
}; |
If you want to authorize your lambda functions using Cognito user pool, you need to add a resource Authorizer:
MyCognitoAuthorizer: | |
Type: AWS::ApiGateway::Authorizer | |
Properties: | |
AuthorizerResultTtlInSeconds: 300 | |
IdentitySource: method.request.header.Authorization | |
RestApiId: | |
Ref: ApiGatewayRestApi | |
Name: MyCognitoAuthorizer | |
Type: COGNITO_USER_POOLS | |
ProviderARNs: | |
- {"Fn::Join": ["", ["arn:aws:cognito-idp:", {Ref: "AWS::Region"}, ":", {Ref: "AWS::AccountId"}, ":userpool/", Ref: CognitoUserPool]]} |
And add authorizer for selected function, for example:
functions: | |
# This function will add note | |
addNote: | |
handler: handler.addNote | |
events: | |
- http: | |
path: /add/ | |
method: put | |
cors: | |
origin: '*' | |
headers: | |
- Content-Type | |
- Authorization | |
allowCredentials: false | |
authorizer: | |
type: COGNITO_USER_POOLS | |
authorizerId: | |
Ref: MyCognitoAuthorizer |
Integrating frontend with Cognito using amazon-cognito-identity-js
Registering a user with the application. One needs to create a CognitoUserPool object by providing a UserPoolId and a ClientId and signing up by using a username, password.
var poolData = { | |
UserPoolId: '...', // Your user pool id here | |
ClientId: '...', // Your client id here | |
}; | |
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); | |
userPool.signUp('username', 'password', attributeList, null, function( | |
err, | |
result | |
) { | |
if (err) { | |
alert(err.message || JSON.stringify(err)); | |
return; | |
} | |
var cognitoUser = result.user; | |
console.log('user name is ' + cognitoUser.getUsername()); | |
}); |
To login you need to authenticate a user with the Amazon Cognito Identity service.
var authenticationData = { | |
Username: 'username', | |
Password: 'password', | |
}; | |
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails( | |
authenticationData | |
); | |
var poolData = { | |
UserPoolId: '...', // Your user pool id here | |
ClientId: '...', // Your client id here | |
}; | |
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); | |
var userData = { | |
Username: 'username', | |
Pool: userPool, | |
}; | |
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData); | |
cognitoUser.authenticateUser(authenticationDetails, { | |
onSuccess: function(result) { | |
var accessToken = result.getAccessToken().getJwtToken(); | |
}, | |
onFailure: function(err) { | |
alert(err.message || JSON.stringify(err)); | |
}, | |
}); |
Signing out from the application.
cognitoUser.signOut();
Retrieving the current user from local storage.
var poolData = { | |
UserPoolId: '...', // Your user pool id here | |
ClientId: '...', // Your client id here | |
}; | |
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData); | |
var cognitoUser = userPool.getCurrentUser(); | |
if (cognitoUser != null) { | |
cognitoUser.getSession(function(err, session) { | |
if (err) { | |
alert(err.message || JSON.stringify(err)); | |
return; | |
} | |
console.log('session validity: ' + session.isValid()); | |
// NOTE: getSession must be called to authenticate user before calling getUserAttributes | |
cognitoUser.getUserAttributes(function(err, attributes) { | |
if (err) { | |
// Handle error | |
} else { | |
// Do something with attributes | |
} | |
}); | |
}); | |
} |