Oscar_sgc
Oscar_sgc

Reputation: 350

AWS API Gateway 401 Unauthorized when lambda fails

Im using Serverless framework to deploy a set of API's running on API Gateway using cognito as authorizer. Everything seemed to work but i found an issue that when lambda crashes for some reason (maybe time out or some unhandled exception), API Gateway returns 401 Unauthorized.

I added some gateway responses and I can handle some of the errors but even if I get the initial error, I keep receiving the 401 Unauthorized in Frontend.

This is part of my serverless.yml file:

getSimulationStatus:
    handler: getSimulationStatus.handler
    events:
    - http:
        path: /simulation/status
        method: post
        cors: true
        authorizer:
          arn: arn:aws:cognito-idp:us-east-1:${self:custom.settings.COGNITO_ARN}

resources:
  Resources:
    GatewayResponseDefault5XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
          gatewayresponse.header.Access-Control-Allow-Methods: "'*'"
        ResponseType: DEFAULT_5XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'
    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
          gatewayresponse.header.Access-Control-Allow-Methods: "'*'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'

For the frontend im using Angular and I have an error interceptor that captures all this events. Currently im forcing a 504 Request time out and Im able to see that, but also the 401 Unauthorized appears.

This is the code for the interceptor:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            console.log("error captured", err);
            return throwError(err.error.message);
        }));
}

The idea is to sign out if I receive 401 from backend but currently if any of my lambdas fails, Im immediately logged out.

Any Idea on what could be the problem?

Edit: This is a capture from web console: enter image description here

Upvotes: 1

Views: 2921

Answers (1)

Derek Men&#233;nedez
Derek Men&#233;nedez

Reputation: 2377

I have a better solution.Why you don't verify if the token it's valid before send the request to api gateway?

you can install this:

npm i jwt-decode

In my case, I always have a fuction that return me the headers and that allows me to validate in that function the token on every call to the API.

Here a function that validate the token (you only need to pass the token of cognito if you are ussing amplify or something like that).

import jwt_decode from "jwt-decode";

....
some code
....

tokenValidator(){
    if(localStorage.getItem('access_token') == null){
         //call signout cognito and go to login
    }
        
    const decoded = jwt_decode(localStorage.getItem('access_token'));

    if (decoded.exp === undefined) return null;
  
    const date = new Date(0); 
    date.setUTCSeconds(decoded.exp);

    if(new Date() > date){
        //call signout cognito and go to login
    }
  }

This solution prevents your problem.

Upvotes: 1

Related Questions