3rdSenna
3rdSenna

Reputation: 376

Serverless framework - Lambda function with Authorizer COGNITO_USER_POOLS always return "Unauthorized"

I can't figure out what's wrong on my Authorization.

I've a Hello function which only returns a simple a static message. If I deploy without set "Authorizer", it works. I've tested on Postman. The issue starts when I try adding Authorizer.

I've my Cognito fully working. On my front end I can sign up, then do a login and then get the Token from this login session.

When I go to Postman and test, I'm always getting "unauthorized" as answers. On Postman I test on GET method, on "Headers" tab I added "Authorization" attribute and pasted on value the token that I've from Login session. I also tested this on the value field the prefix "bearer" as some places recommended. No success.

enter image description here

I've been trying for the past week solve this issue. Please, any help will be extremely useful.

serverless.yml

provider:
  name: aws
  runtime: nodejs10.x
  stage: dev
  region: eu-west-1
  environment: 
    MY_TABLE: ${self:custom.myStage}_${self:custom.settings.tb_items}
    MY_STAGE: ${self:custom.myStage}
    MY_DOMAIN: ${self:custom.myDomain}
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "dynamodb:GetItem"
        - "dynamodb:PutItem"
        - "dynamodb:UpdateItem"
        - "dynamodb:DeleteItem"
        - "dynamodb:Scan"
      Resource: "*"

functions:
  hello:
    handler: ${self:custom.pathFunc}/phraseOption.hello
    events:
      - http: 
          method: GET 
          path: hello
          cors: true
          integration: lambda-proxy
          authorizer:
            type: COGNITO_USER_POOLS
            authorizerId:
              Ref: ApiGatewayAuthorizer

resources:
  Resources:
    CognitoUserPool:
      Type: "AWS::Cognito::UserPool"
      DeletionPolicy: Retain
      Properties:
        MfaConfiguration: OFF
        UserPoolName: ${self:custom.myStage}_aePool
        EmailVerificationSubject: 'Your verification Code'
        EmailVerificationMessage: 'Use this code to confirm your sign up {####}'
        AutoVerifiedAttributes:
          - email
        UsernameAttributes:
          - email
        Policies:
          PasswordPolicy:
            MinimumLength: 6
            RequireLowercase: False
            RequireNumbers: False
            RequireSymbols: False
            RequireUppercase: False
    CognitoUserPoolClient:
      Type: "AWS::Cognito::UserPoolClient"
      DeletionPolicy: Retain
      Properties:
        ClientName: ${self:custom.myStage}_aePoolClient
        GenerateSecret: False
        UserPoolId:
          Ref: CognitoUserPool
    ApiGatewayAuthorizer: 
      Type: AWS::ApiGateway::Authorizer
      Properties: 
        Name: CognitoUserPool
        Type: COGNITO_USER_POOLS
        IdentitySource: method.request.header.Authorization
        RestApiId: 
          Ref: ApiGatewayRestApi
        ProviderARNs: 
          - Fn::GetAtt:
              - CognitoUserPool
              - Arn

phraseOptions.js

module.exports.hello = (event, context, callback) => {
  const response = {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Your function executed successfully!',
      input: event,
    }),
  };

  callback(null, response);
};

I can see the function was created with the correct Auth:

enter image description here

Also Authorizer create as expected (I guess)

enter image description here

Swagger

---
swagger: "2.0"
info:
  version: "2019-10-07T21:24:17Z"
  title: "XXXXXX"
host: "XXXXXX"
basePath: "/dev"
schemes:
- "https"
paths:
  /getPhrase:
    get:
      responses: {}
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Credentials:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
  /hello:
    get:
      responses: {}
      security:
      - CognitoUserPool: []
  /item:
    post:
      responses: {}
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Credentials:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
  /item/{itemId}:
    get:
      responses: {}
    put:
      responses: {}
    delete:
      responses: {}
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Credentials:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
  /items:
    get:
      responses: {}
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Credentials:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
securityDefinitions:
  CognitoUserPool:
    type: "apiKey"
    name: "Authorization"
    in: "header"
    x-amazon-apigateway-authtype: "cognito_user_pools"

Upvotes: 1

Views: 1537

Answers (1)

3rdSenna
3rdSenna

Reputation: 376

I've figure out what was wrong!

The server side was Ok. The issue on testing it on Postman was the Token. I was using "cognitoUser.signInUserSession.accessToken.jwtToken", but supposed to be "cognitoUser.signInUserSession.idToken.jwtToken".

Everything working as expected now.

Upvotes: 6

Related Questions