For a React-Native application I would like to send Cognito credentials with a GET request to my API. I'm following the following approach [1]:
Cognito UserPool + Cognito Identity Pool + API Gateway + AWS_IAM Authorization + Cognito Credentials
At this current stage I can receive Cognito credentials for the associated role as explained here [2]
Now, I would like to use these credentials to access my API. I have set the Authorization Type to AWS_IAM in my API Gateway.
But I have no idea HOW i could send my Cognito credentials with my GET request. I have plowed through the documents, but it seems that it only explains the different SDKs.
let response = await fetch('https://12345.execute-api.us-east-1.amazonaws.com/dev/single', {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
// What to do here??
},
Any pointers and or documentation I could look at?
[1] https://forums.aws.amazon.com/thread.jspa?threadID=230452
[2] http://mobile.awsblog.com/post/TxGNH1AUKDRZDH/Announcing-Your-User-Pool-in-Amazon-Cognito
I do not fully understand what you mean by sending your Cognito credential to API Gateway, but if you want to use the credential you get from Cognito, you need to use that credential to sign the request to API Gateway.
I suggest you can use the signer in AWS react native SDK to sign the request or some 3rd parties library like react-native-aws-signature
Related
In AWS, I have built an API gateway which invokes a Lambda function. Users gain access by logging in to a Cognito User Pool associated with a Cognito Federated Identity Pool and the associated IAM roles contain API invoke permissions. The API Gateway method is a POST request.
If I use the User Pool as the authorizer of the API Gateway I am able to successfully trigger the Lambda function via an ajax request in my javascript web app - note though, this grants the same access to every user in the pool. I am trying to create different Cognito User Group based access for different methods and because I apparently cannot specify a different User Group for each method when using the Cognito User Pool as the authorizer, I am now seeing if I can secure the API using AWS_IAM as the API authorizer. However, if I select AWS_IAM as the authorizer I get back:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
What might be the problem? How do I set up CORS correctly for this scenario and what should my ajax request look like in the client javascript? Does cognito take care of signing for me or do I need to do something to headers?
When I used the Cognito User Pool I had:
$.ajax({
method: 'POST',
url: _config.api.invokeUrl + '/savesurv',
headers: {
Authorization: authToken
},
data: JSON.stringify(Data),
contentType: 'application/json',
success: callback,//console.log("complete"),
error: function ajaxError(jqXHR, textStatus, errorThrown) {
console.error('Error requesting save: ', textStatus, ', Details: ', errorThrown);
console.error('Response: ', jqXHR.responseText);
alert('An error occured when requesting to save:\n' + jqXHR.responseText);
}
});
This worked in that case, do I need to change it when using AWS_IAM as authorization for the API Gateway?
The problem here is that when you changed to use AWS_IAM as the authorizer for your API Gateway method the request must now contain specific amazon headers and not just Authorization header as you have specified.
This is called a signed Sigv4 request and more information on how to create the request can be found here:
https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html
So to answer your question, Cognito will not take care of the signing and you do have to do additional steps, or get a framework to handle that for you.
The way I got this to work was to use Amplify (https://aws-amplify.github.io/) to generate my API requests and this framework will take care of signing the requests for you.
I appreciate that is quite a high level answer but to go into Amplify here would be a bit off topic for your question.
It's worth noting that if you decode your JWT ID Token (the one that you are passing as authToken) using a tool such as https://jwt.io/ it contain details of the groups which your user is in which may give you something to work with. I'm assuming that API Gateway will validate the authenticity of the token so you can rely on the values it contains. Then in API Gateway you can get access to this detail.
How do I call API gateway with postman with cognito?
Tried to use AWS Signature in postman and this did not work.
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
I am using hosted UI in cognito if that makes a difference. I see that there is an Oauth 2.0 option in postman but dont know how to fill out the fields.
So my api works when I pass Authorization in the header with the id_token. Without the id_token is there any other way?
thanks
If you are using a Cognito user pool and have your API Gateway authorizer set to user pool, then you need to pass either the id or access token in the Authorization header.
If you are using a Cognito identity pool and have your API Gateway authorizer set to AWS_IAM you need to use AWS signatures
I'm developing web app based on Amazon API Gateway. Now I created Facebook login and successfully logged into website. but when I call another API, everything gone. I think I should pass Cognito token when call API everytime. am I right?
if yes, how to pass Cognito token to API? like header? or another way?
Thanks,
You are using the "Basic Authflow" from cognito identity, which means you will need to get credentials for your users by calling STS's "AssumeRoleWithWebIdentity". Here is some documentation to help: http://docs.aws.amazon.com/cognito/devguide/identity/concepts/authentication-flow/
Once you have credentials, you can instantiate the API Gateway Client:
var client = apigClientFactory.newClient({
accessKey: ACCESS_KEY,
secretKey: SECRET_KEY,
sessionToken: SESSION_TOKEN });
The keys and tokens come from the result of the "AssumeRoleWithWebIdentity" call.
If you have configured your IAM roles, and Authorizations correctly you should be able to access your API.
Here is the documentation describing how to configure the roles & authorization: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-method-settings.html#how-to-method-settings-callers-console
Also, here is how to enable CORS - http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
I am building a web app that authenticates via AWS Cognito, and uses an existing API gateway configuration to talk to Lambda functions.
In my app, when I authenticate, I get the following data back from Cognito:
The sample headers I've been given to authenticate to the Amazon API gateway look like this (x's added for obfuscation):
Content-type: application/json
Host: <API Gateway host>
X-Amz-DateL <Date>
Authorization:
AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXX/20170222/ap-southeast-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f25e2a18d8c81fe9e7XXXXXXXXXXXXXXXXb7d586d24a3e39
Access_key:XXXXXXXX (this is a large string)
My question is what information do I need from my cognito result to craft the headers that I need to connect to the api?
I'm using Vue.js as a Javascript front end, and I've looked at the AWS SDK for Javascript but not sure if that helps me - for the moment I feel crafting the headers manually may be easier?
I believe what you're trying to do is authorize your already authenticated users. Explanation of the difference between authorization and authentication can be found here
In the case of authorization, you can create a Custom Authorizer. However, since you're using Amazon Cognito, be sure to create a Cognito User Pool Authorizer
Essentially, you'll use the IdToken from Cognito and pass it as the Authorization header to your authorizer function.
See also Integrating Amazon Cognito User Pools with API Gateway
I'm developing web app based on Amazon API Gateway. Now I created Facebook login and successfully logged into website. but when I call another API, everything gone. I think I should pass Cognito token when call API everytime. am I right?
if yes, how to pass Cognito token to API? like header? or another way?
Thanks,
You are using the "Basic Authflow" from cognito identity, which means you will need to get credentials for your users by calling STS's "AssumeRoleWithWebIdentity". Here is some documentation to help: http://docs.aws.amazon.com/cognito/devguide/identity/concepts/authentication-flow/
Once you have credentials, you can instantiate the API Gateway Client:
var client = apigClientFactory.newClient({
accessKey: ACCESS_KEY,
secretKey: SECRET_KEY,
sessionToken: SESSION_TOKEN });
The keys and tokens come from the result of the "AssumeRoleWithWebIdentity" call.
If you have configured your IAM roles, and Authorizations correctly you should be able to access your API.
Here is the documentation describing how to configure the roles & authorization: http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-method-settings.html#how-to-method-settings-callers-console
Also, here is how to enable CORS - http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html