I have a listUsers
function which was working perfectly with cognito authorizer.
Since I’ve changed it to a Lambda Authorizer, it returns a 500
HTTP status code.
serverless.yml
:
provider:
httpApi:
cors: true
authorizers:
customAuthorizer:
type: request
functionName: custom-authorizer
functions:
custom-authorizer:
handler: authorizer.handler
listUsers:
handler: src/users/index.listUsersHandler
events:
- httpApi:
path: /users
method: get
authorizer: customAuthorizer
authorizer.js
:
const { CognitoJwtVerifier } = require('aws-jwt-verify');
const Cognito = require('../shared/Cognito');
module.exports.handler = async (event) => {
const authHeader = event.headers.authorization;
if (!authHeader) {
console.log('No auth header');
return {
isAuthorized: false,
};
}
const token = authHeader.split(' ')[1];
console.log(token);
const verifier = CognitoJwtVerifier.create({
userPoolId: Cognito.UserPoolId,
tokenUse: 'access',
clientId: Cognito.ClientId,
});
let payload = null;
try {
payload = await verifier.verify(token);
console.log('Token is valid. Payload:', payload);
return {
isAuthorized: true,
};
} catch {
console.log('Token is invalid.');
return { isAuthorized: false };
}
};
When I make a GET request to /users
it correctly redirects to my custom-authorizer & in the logs I can see that the token is valid.
However, it never runs the actual listUsers
function and in Postman I get:
{
"message": "Internal Server Error"
}
2
Answers
I fixed this by adding this:
The expected output of a Lambda authoriser is essentially a principal identifier & a policy document:
Allow
/Deny
the API Gateway execution serviceexecute-api:Invoke
)Therefore, the current Lambda authoriser response is completely incorrect, which is why you get an internal server error:
As a good starting point, use the
methodArn
property on theevent
object (event.methodArn
) as the resource. This is the the ARN of the method that the caller is requesting, provided by AWS.This method will return a minimal but correct authoriser response:
Usage: