sst.dev icon indicating copy to clipboard operation
sst.dev copied to clipboard

Can't access event.requestContext.authorizer.claims

Open rafapetter opened this issue 7 years ago • 13 comments

Hi there, I have an issue after I've included the new changes. On the serveless.yml I have set a function like below.

rec-list:

    handler: rec-list.main
    events:
        - http:
            path: recs
            method: post
            cors: true
            authorizer: aws_iam

But when I call the api I can't access custom fields from the cognito user like I used before:

event.requestContext.authorizer.claims['custom:account']

I get an error saying the authorizer is undefined. Any ideas how to get the cognito user custom fields with the new changes?

rafapetter avatar Jul 21 '17 23:07 rafapetter

@rafapetter That's a really good question. With the IAM way of authorization you don't have direct access to the custom attributes of your User Pool. While this sounds bad, it kinda makes sense because the Identity Pool is just tying different identity providers (User Pool, FB, or Google) together.

I'm not sure what you are using the custom attribute for but you might want to look into Cognito Sync - http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-sync.html. What are you storing in the custom field?

jayair avatar Jul 24 '17 21:07 jayair

@jayair, first of all, great tutorial. I've forward it to a few friends that wanted to dip their toes on React, and everyone loved it.

Ok, to your question... I've created a custom field called account, which is an ID to link one or more users in my app to the same organization. It would have the same role as userId in your tutorial, except that I need that record to be readable to other users from the same organization.

To solve that I might actually need to send account ID on almost every api request. But I was trying to avoid that, by getting the account ID through the event.requestContext.

Do you think I could solve that by using Cognito Sync?

rafapetter avatar Jul 24 '17 22:07 rafapetter

@rafapetter Thanks for the kind words.

AFAIK, with Sync you can very easily get/put something on a per user basis on the client side. I haven't looked into reading it on the Lambda side yet. But from the sounds of it you just want it on the client?

You can read a bit more about Sync here - https://github.com/aws/amazon-cognito-js#usage.

jayair avatar Jul 24 '17 23:07 jayair

@jayair Actually, I'm looking for a solution on the lambda side. I'm currently calling getUserAttributes method when the page loads, so that already brings me the user custom fields.

I guess Cognito Sync could replace it if I needed any offline operation, but currently it's not the case. And even if I change I would still need to keep passing the custom field, account ID, on almost every api call to lambda. Which means I would have to replace the GET for POST calls. So I'm not sure if it's safe to pass the ID like that, since it represents the partition key of most of my DynamoDB tables.

rafapetter avatar Jul 25 '17 13:07 rafapetter

@rafapetter I see. That does seem tricky.

Out of curiosity, how come you aren't storing this account id in the DB?

jayair avatar Jul 25 '17 19:07 jayair

I am. There's a table called Account, which stores all organization related fields. And every other table related to Account has account_id in the primary key, as the partition key.

For instance, there's a table called "Channel" which has a many-to-one relationship with "Account". So the primary key for Channel is:

Partition Key: account_id
Sort Key: channel_id

Then, on lambda, to access channel records from an specific account I do have to query with account_id.

rafapetter avatar Jul 25 '17 20:07 rafapetter

@rafapetter I might not be completely clear on this but do you have a mapping of the user_id to account_id in the database? If you do then you wouldn't need to pass it in with every request right?

jayair avatar Jul 27 '17 19:07 jayair

@jayair I'm sorry for the long delay.

To your question, yes I do. I was just trying to avoid an additional query on DynamoDB for every call made to the API.

I'm currently reading into the newest updates from your tutorial. The session expiration was definitely a hard problem, thanks for finding a solution.

rafapetter avatar Oct 04 '17 13:10 rafapetter

@jayair I'm sorry for the long delay.

To your question, yes I do. I was just trying to avoid an additional query on DynamoDB for every call made to the API.

I'm currently reading into the newest updates from your tutorial. The session expiration was definitely a hard problem, thanks for finding a solution.

@rafapetter Did you ever figure out how to access the custom:attributes in Cognito from event.requestContext???

I have a primary accountID that I need to capture from Cognito that I have defined as a custom:attribute also. I want to get it from Lambda on the backend because I want to make sure that this ID is coming from an authenticated user and not my db. Based on the ID I get from Cognito as stored in the custom:attributes for this authenticated user, then and only then do I want to query my db.

Im having trouble figuring out how to get this data from event.requestContext...

Ive tried ":accountId": event.requestContext.authorizer.claims["custom:accountId"], but Im getting an undefined response.

Anybody have any ideas?

lopezdp avatar Sep 14 '19 15:09 lopezdp

@lopezdp ,

Are you able to access the custom claims through event.requestContext.authorizer.claims?

awkward-minion avatar Jan 27 '20 13:01 awkward-minion

@lopezdp ,

Are you able to access the custom claims through event.requestContext.authorizer.claims?

Oh boy did I solve this... Basically helped me to create the Authorization strategy I now use on every project. Do me a favor; Ill share my code and the answer if you ask the question on stack overflow. Copy the link to the question and send it to me in a reply here and Ill give it to you there... I noticed of all the questions on SO for this issue, absolutely none of them have the correct answer. I need my SO Points! :)

Its not going to come from event.requestContext.authorizer.claims

lopezdp avatar Jan 29 '20 14:01 lopezdp

@lopezdp ,

Are you able to access the custom claims through event.requestContext.authorizer.claims?

@lakshmajim

I found the questions on SO that deal with this issue and submitted a couple of my answers for comment. Here is my response:

https://stackoverflow.com/questions/50574425/get-cognito-user-pool-identity-in-lambda-function/59973934#59973934

lopezdp avatar Jan 29 '20 19:01 lopezdp

@lopezdp , Are you able to access the custom claims through event.requestContext.authorizer.claims?

Oh boy did I solve this... Basically helped me to create the Authorization strategy I now use on every project. Do me a favor; Ill share my code and the answer if you ask the question on stack overflow. Copy the link to the question and send it to me in a reply here and Ill give it to you there... I noticed of all the questions on SO for this issue, absolutely none of them have the correct answer. I need my SO Points! :)

Its not going to come from event.requestContext.authorizer.claims

As you mentioned your question link: https://github.com/AnomalyInnovations/serverless-stack-com/issues/115 I am interested in this as may be it can solve my issue https://stackoverflow.com/questions/71763782/unit-testing-how-to-send-path-parameter Any idea, please share

emailsutapa avatar Apr 06 '22 08:04 emailsutapa