AWS 无服务器自定义 jwt 授权方 lambda 设置 cors 响应

Posted

技术标签:

【中文标题】AWS 无服务器自定义 jwt 授权方 lambda 设置 cors 响应【英文标题】:AWS Serverless custom jwt authorizer lambda set cors response 【发布时间】:2019-12-15 20:07:04 【问题描述】:

我有一个 rest 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 标头添加到我的所有 lambda 响应中。 在谷歌上,我遇到了this 答案,我尝试将这些添加到 default_4xx、default_5xx 和过期令牌响应中

但是,我仍然遇到同样的错误 -

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.

那么,我在这里遗漏了什么吗?或者任何人都可以在这里帮助找到并解决这个问题?

【问题讨论】:

【参考方案1】:

假设您关注this example,您应该将资源部分添加到您的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'

https://github.com/serverless/examples/blob/acfa06e6a93c1cb6e5d9306e65675d1acdec5eb3/aws-node-auth0-custom-authorizers-api/serverless.yml#L36

另外,我将首先在POSTMAN(或任何其他类似工具)中测试 API,以确保在处理 CORS 之前一切正常。

【讨论】:

以上是关于AWS 无服务器自定义 jwt 授权方 lambda 设置 cors 响应的主要内容,如果未能解决你的问题,请参考以下文章

无服务器框架 AWS 跨账户自定义授权方

AWS 自定义授权方 - 从 cookie 获取令牌

通过自定义授权方方法使用 Auth0 授权 AWS APIGateway

如何使用无服务器部署没有身份源的 API Gateway 自定义授权方?

如何为 AWS API Gateway 自定义授权方配置 CORS?

未调用 AWS API Gateway 自定义授权方