如何使用基于网站的 ExpressJs 设置 CORS 和 JWT 令牌验证

Posted

技术标签:

【中文标题】如何使用基于网站的 ExpressJs 设置 CORS 和 JWT 令牌验证【英文标题】:How to set up CORS and JWT token validation with ExpressJs based on website 【发布时间】:2021-08-30 09:30:40 【问题描述】:

所以基本上,我有两个具有不同子域的网站。第一个不需要 JWT Token 验证,但第二个需要验证。

只有当原点是https://app.website.com时,如何使用app.use(authorization)

import cors from 'cors';

if (process.env.NODE_ENV === 'development') 
  app.use(cors());
 else 
  const whitelist = ['https://www.website.com', 'https://app.website.com'];
  app.use(
    cors(
      origin: function (origin, callback) 
        if (origin && whitelist.indexOf(origin) !== -1) 
          return callback(null, true);
        
        return callback(new Error('Forbidden'), false); 
      ,
      optionsSuccessStatus: 204
    )
  );
  app.use(authorization);

JWT 验证作为中间件,我尝试检查 req.get('origin') 但它未定义..

import admin from '../helpers/firebase.helper';

const authorization = async (
  req,
  res,
  next
): Promise<void> => 
  if (req.headers?.authorization?.startsWith('Bearer ')) 
       const idToken = req.headers.authorization.split('Bearer ')[1];
    try 
      const decodeToken = await admin.auth().verifyIdToken(idToken);
      req.current = decodeToken;
      next();
     catch (err) 
      res.status(StatusCodes.UNAUTHORIZED).send('UnAuthorized');
    
   else 
    res.status(StatusCodes.UNAUTHORIZED).send('UnAuthorized');
  
;

第一个站点 www.welcome.com 使用 Nextjs(服务器端渲染)构建,第二个站点使用 React create app(客户端渲染)构建。因此,当我检查 req.get('origin') 的 react create app 请求时,它工作正常,但对于来自 nextjs 应用程序的请求,它是未定义的。

图表

【问题讨论】:

你试过cors( origin: true, credentials: true )吗?但为此,您需要一个启用 SSL 的服务器。并确保您的 JWT cookie 上有 sameSite: "none" 属性 我试过了,但没有任何改变 【参考方案1】:

最后,我解决了这个问题。问题出在 NextJs 上,我正在使用 getserversideprops 进行服务器端请求(服务器到服务器时没有 CORS),所以我转向基本客户端请求,然后它工作正常。我可以访问req.origin,所以我可以检查来源。

【讨论】:

【参考方案2】:

您应该能够使用req.hostname 来获取您收到请求的主机。您可以在文档中查看请求对象的其他属性:http://expressjs.com/en/api.html#req

【讨论】:

是的,我有req.hostname,但我不知道为什么它等于服务器主机。也许是因为我的www.website.com 是用 Nextjs 构建的(服务器端渲染).. 嗯,所以也许我误解了什么。您是否有一个监听两个不同子域的后端?或者您在调用相同后端的两个不同子域上有一个后端和两个不同的前端? 啊,所以我有 2 个前端(nextjs,创建反应应用程序)和 1 个后端(expressjs)。 2个前端调用相同的后端,前端是子域www for nextjs和app for react。我创建了一个图表link 来说明它。 是的,那么主机名对你没有用 - 我以为你有两个域的后端。 req.hostname 应该包含正在处理请求的主机(被调用的主机)。尝试检查引用标题,也许它会包含正确的调用者信息。看起来nextjs的客户端没有正确设置原始标头(但也许它应该由浏览器设置?不确定) 是的,我尝试检查引用标头,但它未定义.. 这很奇怪,因为当我检查 req.host 等于 nextjs 请求的后端 URL 时。所以我想我必须用 nextjs 配置一些东西。

以上是关于如何使用基于网站的 ExpressJs 设置 CORS 和 JWT 令牌验证的主要内容,如果未能解决你的问题,请参考以下文章

将 Google Cloud Platform 的错误报告与 ExpressJS 一起使用

我的 ExpressJS 网站和 socket.io 端口可以使用相同的端口吗?

用户捐赠 - ExpressJS,Angular 9

如何在expressjs中获取cookie值

使用async/await——Nodejs+ExpressJs+Babel

刷新页面显示找不到文件错误如何使用 [angular js + NodeJS/ExpressJS] 解决