Zeit (Vercel) 现在无服务器身份验证请求由于 CORS 而失败

GMa*_*olo 11 javascript authorization cors serverless vercel

我不能这样做既可以当正确处理CORS问题PATCH/ POST/PUT从浏览器发送一个请求,Authorization一个头Bearer token(这个工程的浏览器和正确外GET的请求)在现在时代周报无服务器

如果有帮助,我将Auth0用于授权端。


这是我的now.json标题部分,我为这些尝试了很多组合,但在浏览器中都没有成功。

now.json 中的标题


  1. 我尝试使用 npmcors包但没有成功
  2. 试图添加routesnow.json
  3. 尝试使用在无服务器功能的顶部设置标题 res.addHeader()
  4. 还尝试OPTIONS手动处理请求执行此变体:

OPTIONS 方法自定义处理

最后,这是我得到的错误

Access to XMLHttpRequest at 'https://api.example.org/api/users' from origin 'https://example.org' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Run Code Online (Sandbox Code Playgroud)

不知道我错了什么或如何正确处理这个问题。

ham*_*mpe 6

我对 CORS 和 Vercel 无服务器功能有非常类似的问题。

\n\n

经过多次尝试 \xe2\x86\x92 失败的过程后,我刚刚找到了解决方案。

\n\n
\n\n

解决方案

\n\n

总览

\n\n

最简单的解决方案,只需使用micro-cors

\n\n

并有一个类似的实现;

\n\n
import { NowRequest, NowResponse } from \'@now/node\';\nimport microCors from \'micro-cors\';\n\nconst cors = microCors();\n\nconst handler = (request: NowRequest, response: NowResponse): NowResponse => {\n  if (request.method === \'OPTIONS\') {\n    return response.status(200).send(\'ok\');\n  }\n\n  // handle incoming request as usual\n};\n\nexport default cors(handler);\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

更长的版本,但没有任何新的依赖项

\n\n

用于vercel.json处理请求标头

\n\n

vercel.json

\n\n
{\n  "headers": [\n    {\n      "source": "/.*",\n      "headers": [\n        {\n          "key": "Access-Control-Allow-Origin",\n          "value": "*"\n        },\n        {\n          "key": "Access-Control-Allow-Headers",\n          "value": "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept"\n        },\n        {\n          "key": "Access-Control-Allow-Credentials",\n          "value": "true"\n        }\n      ]\n    }\n  ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

经过自我尝试,上面的设置中有2个重要的键,

\n\n
    \n
  1. 你必须设置Access-Control-Allow-Origin为你想要的
  2. \n
  3. Access-Control-Allow-Headers必须将 Access-Control-Allow-Origin其纳入其中。
  4. \n
\n\n

那么在无服务器功能中,您仍然需要处理飞行前请求

\n\n

/api/index.ts

\n\n
const handler = (request: NowRequest, response: NowResponse): NowResponse => {\n  if (request.method === \'OPTIONS\') {\n    return response.status(200).send(\'ok\');\n  }\n\n  // handle incoming request as usual\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

我建议通读micro-cors中的代码,它是非常简单的代码,你可以在几分钟内理解它会做什么,这使得我不关心将其添加到我的依赖项中。

\n


GMa*_*olo 5

我能够使用micro-cors绕过这个问题。

我检查了它的代码,它与我res.setHeader手动使用自己尝试做的事情没有太大区别,我猜可能错过了一些东西。

尽管如此,我不明白为什么 中的设置now.json无法正常工作,我需要在无服务器功能中手动执行此操作。

无论如何,万一其他人发现这篇文章,我最终会得到这样的结果:

import micro from "micro-cors";

function MyApi(req, res) {
  if (req.method === "OPTIONS") {
    return res.status(200).end();
  }
  // handling other requests normally after this
}

const cors = micro();

export default cors(MyApi);
Run Code Online (Sandbox Code Playgroud)

我可能会用自己编写的解决方案再试一次,以便更好地理解出了什么问题,也因为我不想要额外的依赖。

如果我这样做,将更新此答案。


编辑:经过更深入的检查后,我发现另一个问题是库在解析失败时express-jwt专门更改了res对象jwt

我有一个小型中间件,它通过以下方式破坏了一切:

await authValidateMiddleware(req, res);
Run Code Online (Sandbox Code Playgroud)

await失败时,它破坏了所有内容,因为express-jwtres不知不觉中更改了标题(设置错误),然后我尝试res手动设置标题,尝试自己正确处理错误,因此引发了有关res多次更改标题”的问题