aws-samples / serverless-patterns

Serverless patterns. Learn more at the website: https://serverlessland.com/patterns.
https://serverlessland.com
Other
1.47k stars 858 forks source link

How to provide {tokenProvidedByCognito} to cognito-restapi? #2254

Open ModalityZ opened 1 month ago

ModalityZ commented 1 month ago

I'm trying to follow the Testing step of https://github.com/aws-samples/serverless-patterns/tree/main/cognito-restapi It's not clear what kind of value to use for {tokenProvidedByCognito}.

What I want to do is invoke this api from my browser page inside the onSuccess callback of initiateAuth. So I loaded that page while breakpointing in that callback, and when it reached the point of calling getAccessToken().getJwtToken(); on the response to initiateAuth, I copied the JWT token and then pasted it into my local terminal:

curl -i https://mySamDeployedEndpoint.execute-api.us-west-2.amazonaws.com/Prod -H "authorizationToken: theJwtThatICopied"

But that returns a 401:

HTTP/2 401 
content-type: application/json
content-length: 26
date: Mon, 15 Apr 2024 06:58:23 GMT
x-amzn-requestid: [omitted]
x-amzn-errortype: UnauthorizedException
x-amz-apigw-id: [omitted]
x-cache: Error from cloudfront
via: 1.1 [omitted].cloudfront.net (CloudFront)
x-amz-cf-pop: HEL51-P1
x-amz-cf-id: [omitted]

The sam-app-AppFunction-[omitted] Lambda has no CloudWatch log content yet to look at, and I can't find any logs in the associated API Gateway entry.

Btw, earlier I updated template.yaml with Runtime: nodejs20.x because Lambda's no longer support the node14.x setting in all the sam templates I've looked at.

ModalityZ commented 1 week ago

Partial answer: {tokenProvidedByCognito} is a surprisingly vague placeholder for AWS documentation. It does not specify whether it should be an access token, as I assumed, or an identity token, which turned out to be correct.

Also, despite the initiateAuth response having a getIdToken method, the result given by this method is not directly usable as {tokenProvidedByCognito}. What one must do to get a usable value is getIdToken().getJwtToken().

Copy-pasting that value into the curl template of the Testing section of https://github.com/aws-samples/serverless-patterns/tree/main/cognito-restapi will result in a 200 response code and json that reflects the request properties. That is what a pass of the curl test looks like.

However, making a GET using the same authorization header from one's page that provides the JWT will result in a CORS Blocked error. It seems that https://github.com/aws-samples/serverless-patterns/blob/main/cognito-restapi/template.yaml must be edited in some way to enable CORS for the (sub)domains that one wants to permit. This seems like a poor security choice for a recommended template, and that instead the absence of any domain (as would be the case for curl) should result in a Blocked error. The template installation should prompt for the (sub)domains to be allowed.