What is the REST (or CLI) API for logging in to Amazon Cognito user pools
How do i make logins happen via Amazon Cognito REST APIs (for user pools) on platforms for which there is no official SDK? - Note that i am asking for user pools - not identity pools.
Synopsis
Amazon cognito provides 3 kinds of logins:
- federated logins (creates identity pools) - using social connects like FB, Twitter, G+ etc
- AWS managed logins (creates user pools) - using Amazon's own managed signup, signin, forgot password, reset password services
- developer provided logins (my custom designed authentication service managed by myself)
I am using the second one (with User Pools)
Amazon cognito has several SDKs for android, iOS, javascript, Xamarin etc. Cognito also provides REST APIs for building on platforms other than those supported by official SDKs. I am building an app for a different platform and, hence, REST API is my only way as there is no official SDK for my platform.
The Cognito REST API provides various endpoints for 'sign up', 'forgot password', 'confirm verification' etc, but surprisingly, the REST API does not have any endpoint for simple signin / login.
From Cognito CLI API docs I have all the OFFICIAL CLI APIs necessary to "signup users", "confirm signups", "change passwords", "verify phone numbers", "forgot passwords" etc. Surprisingly there is no CLI API mentioned for LOGINs. I was hoping there should be some CLI API like "$ aws cognito-idp log-in
" just like there is for "$ aws cognito-idp sign-up
" or for "$ aws cognito-idp forgot-password
" etc.
Also from this getting started tutorial it talks about "*what should be done with tokens received AFTER successful authentication of a user*". However, it doesn't talk about HOW TO make the successful authentication happen on the first place with Cognito User Pool APIs. Examples are available only for Android, iOS, javascript SDKs. There are no authentication examples available for platforms which do not have SDKs.
Hence, How do i make logins happen via Amazon Cognito REST APIs (for user pools) on platforms for which there is no official SDK?
This curl
command works for me:
curl -X POST --data @aws-auth-data.json \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
https://cognito-idp.us-east-1.amazonaws.com/
Where aws-auth-data.json
is:
{
"AuthParameters" : {
"USERNAME" : "[email protected]",
"PASSWORD" : "yourpassword"
},
"AuthFlow" : "USER_PASSWORD_AUTH",
"ClientId" : "75........................"
}
The user pool client must allow USER_PASSWORD_AUTH
for this to work - that's an AWS-side setting.
Update:
As you pointed out in the comments below, the authentication flow is documented here: http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html. This might help to clarify the authentication flow
It is somewhat counter-intuitive, but it does make sense for mobile apps where you don't want to have the user explicitly sign in, but instead carry tokens around for the user. Note that there is an explicit signin (login) API in the AWS Userpools SDK for iOS. I have not used it, but I suppose it is just an alternate client side API to get through the same InitiateAuth()
followed by a RespondToAuthChallenge()
flow. The iOS signin example is documented here - IOS SDK Example: Sign in a User
Original Post:
The Cognito User Pools API documentation for initiating auth is available here
The way it works becomes clearer if you implement a user pools application in one of the SDK's (I did one in Swift for iOS, it is clarified because the logging of the JSON responses is verbose and you can kind of see what is going on if you look through the log).
But assuming I understand your question: In summary you should InitiateAuth()
and the response to that (from the Cognito User Pools server) is a challenge. Then you do RespondToAuthChallenge()
(also documented in that API doc) and the response to that is an authentication result - assuming that the password / session / token were accepted.
The combination of those two things is, I believe, what you are calling LOGIN, and it works like a login. In the API's, the way it is set up is that attempts to get user information when the user is unauthenticated kicks off that InitiateAuth()
and (in iOS anyway) the API does a callback to the code you write to ask for passwords, and send a RespondToAuthChallenge()
request etc.
Just to add to @andrewjj's answer. You might get back a challenge (NEW_PASSWORD_REQUIRED) as InitiateAuth response. It is when you are being asked to change passport on initial signin.
You can use Postman
or curl
command. This example expects Postman being used.
- InitiateAuth - This step is same as @andrewjj
Add this to Body
as raw
values
{
"AuthParameters": {
"USERNAME": "[email protected]",
"PASSWORD": "temporary-password",
},
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "2s........................"
}
Set headers
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Content-Type: application/x-amz-json-1.1
Send a request to https://cognito-idp.us-east-1.amazonaws.com/
You might have to change region.
If you receive this response then your are ok, otherwise continue with step 2.
{
"AuthenticationResult": {
"AccessToken": "eyJra........",
"ExpiresIn": 3600,
"IdToken": "eyJra........",
"RefreshToken": "eyJjd........",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
- RespondToAuthChallenge - this is new step
In case you receive Challenge back like this one:
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeParameters": {
"USER_ID_FOR_SRP": "1231-......",
"requiredAttributes": "[]",
"userAttributes": "{\"email_verified\":\"true\",\"email\":\"[email protected]\"}"
},
"Session": "Sfas......"
}
You need to set new password. Add this to Body
as raw
values
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeResponses": {
"USERNAME": "[email protected]",
"NEW_PASSWORD": "newpassword"
},
"ClientId": "2s........................",
"Session": "Sfas......(use one from the InitiateAuth response)"
}
Set headers
X-Amz-Target: AWSCognitoIdentityProviderService.RespondToAuthChallenge
Content-Type: application/x-amz-json-1.1
Send a request to https://cognito-idp.us-east-1.amazonaws.com/
You might have to change region.
Do step 1 again to receive tokens.
One of the developers from AWS Cognito team here.
To add to @md-abdul-munim's answer, we recommend using one of the client side SDKs. If you are building a REST API and then a front end which talks to those APIs, it is better to just integrate Cognito from your front end.
If you absolutely need to use Cognito from a back end, the authentication APIs will be available with our GA release. In our Cognito User Pools beta release authentication is only available through client SDKs.
Sharing curl direct may help to anyone
curl -X POST --data @user-data.json \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
https://cognito-idp.<just-replace-region>.amazonaws.com/
file json user-data.json
{"AuthParameters" : {"USERNAME" : "sadfsf", "PASSWORD" : "password"}, "AuthFlow" : "USER_PASSWORD_AUTH", "ClientId" : "csdfhripnv7sq027kktf75"}
make sure your app client does not contain app-secret or create new app without secret. also inside app enable USER_PASSWORD_AUTH