AWS Serverless custom jwt authorizer lambda set cors response

У меня есть api для отдыха, развернутый на aws с бессерверной структурой.

Теперь я создал в нем простой пользовательский авторизатор токенов jwt для авторизации моих конечных точек.

Это мое определение маршрутов в serverless.yml -

loginUser:
  handler: src/controllers/auth.loginUser
  events:
    - http:
        path: auth/local/login
        method: POST
        cors: true

tokenVerifier:
  handler: ./src/helpers/tokenVerifier.auth

userProfile:
  handler: src/controllers/users.me
  events:
    - http:
        path: user/me
        method: GET
        authorizer: tokenVerifier
        cors: true

И это мое определение функции tokenVerifier настраиваемого авторизатора -

const jwt = require('jsonwebtoken'); 

// Policy helper function
const generatePolicy = (principalId, effect, resource) => {
    const authResponse = {};
    authResponse.principalId = principalId;
    if (effect && resource) {
        const policyDocument = {};
        policyDocument.Version = '2012-10-17';
        policyDocument.Statement = [];
        const statementOne = {};
        statementOne.Action = 'execute-api:Invoke';
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    return authResponse;
};

const auth = (event, context, callback) => {

    // check header or url parameters or post parameters for token
    const token = event.authorizationToken;

    if (!token) return callback(null, 'Unauthorized');

    // verifies secret and checks exp
    jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
        if (err) return callback(null, 'Unauthorized');

        // if everything is good, save to request for use in other routes
        return callback(null, generatePolicy(decoded._id, 'Allow', event.methodArn));
    });

};

export {
    auth
};

Также я создал вспомогательную утилиту ответа, которую использую везде, чтобы возвращать ответы пользователям -

const responseHelper = (response, context, callback, status = 404) => {
    eventLogger(["----RESPONSE DATA----", response], context.functionName);
    callback(null, {
        statusCode: status,
        body: JSON.stringify(response),
        headers: {
            "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
            "Access-Control-Allow-Credentials" : true, // Required for cookies, authorization headers with HTTPS
            "Content-Type": "application/json"
        }
    });
};

Итак, как видите, я добавил cors: true к маршрутам yml, а также добавил заголовки cors ко всем своим лямбда-ответам. В Google я наткнулся на этот ответ и попытался добавить их в ответы по умолчанию_4xx, default_5xx и просроченный токен также  ответ шлюза api gw

Но все же я получаю ту же ошибку -

Access to XMLHttpRequest at '<url>/dev/user/me' from origin '<site_url>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Итак, я что-то здесь упускаю? или кто-нибудь может помочь найти и исправить эту проблему здесь?


person Harshit Laddha    schedule 08.08.2019    source источник


Ответы (1)


Предполагая, что вы следуете этому примеру, вы должны добавить часть ресурсов в свой serverless.yml:

resources:
  Resources:
    # This response is needed for custom authorizer failures cors support ¯\_(ツ)_/¯
    GatewayResponse:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: EXPIRED_TOKEN
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        StatusCode: '401'
    AuthFailureGatewayResponse:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: UNAUTHORIZED
        RestApiId:
          Ref: 'ApiGatewayRestApi'
        StatusCode: '401'

Кроме того, я бы сначала протестировал API в POSTMAN (или любом другом подобном инструменте), чтобы убедиться, что все работает как ожидается до обработки CORS.

person Erez    schedule 11.08.2019