MSAL搭配Express与React实现根URL访问鉴权问题求助
问题1解答
原因是Express的中间件和路由是按声明顺序匹配执行的,你当前代码里先声明了app.use(express.static(...))静态资源托管中间件,当用户访问根路径/时,静态中间件会优先检查build文件夹下是否存在默认索引文件index.html,命中后就会直接返回该文件,不会继续执行后续声明的app.get('/')路由。
通配符*不生效也是同样的逻辑:只要静态中间件匹配到了对应资源,就会直接终止链路返回结果,不会走到后续的通配符路由。
问题2解答
完全可以实现根路径直接触发认证,不需要额外新增/login路由,按下面的步骤修改代码即可:
- 调整路由和中间件的声明顺序,把认证相关路由放在静态资源托管之前
- 新增
express-session依赖存储用户登录状态,避免每次访问都重复触发认证 - 修改MSAL的重定向URI为
/redirect路由,回调完成后再跳转回根路径
修改后的核心代码示例:
// 先引入express-session const session = require('express-session'); // 配置session,放在所有路由最前面 app.use(session({ secret: '自定义session密钥', resave: false, saveUninitialized: false, cookie: { secure: process.env.NODE_ENV === 'production' } })); // 认证校验中间件,所有请求先过这一关 const authCheck = (req, res, next) => { // 认证成功后会把用户信息存在req.session.user里 if (req.session.user || req.path === '/redirect') { return next(); } // 未登录触发认证流程 const authCodeUrlParameters = { scopes: ["user.read"], redirectUri: "http://localhost:3000/redirect", }; pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => { res.redirect(response); }).catch((error) => console.log(JSON.stringify(error))); }; // 先加认证中间件 app.use(authCheck); // 处理redirect回调路由 app.get('/redirect', (req, res) => { const tokenRequest = { code: req.query.code, scopes: ["user.read"], redirectUri: "http://localhost:3000/redirect", }; pca.acquireTokenByCode(tokenRequest).then((response) => { // 认证成功,把用户信息存入session req.session.user = response.account; res.redirect('/'); // 回调完成跳回根路径 }).catch((error) => { console.log(error); res.status(500).send(error); }); }); // 最后才托管静态资源 app.use(express.static(path.join(__dirname, './build')));
调整后用户第一次访问根路径时,会先经过认证校验中间件触发MSAL认证流程,回调成功后才会返回前端的静态资源,全程不需要额外的/login路由。
问题3解答
上面的方案已经可以完全避免用户直接访问根路径拿到前端资源:所有请求都会优先经过认证校验中间件,未登录的用户会直接被重定向到微软登录页,根本拿不到build文件夹下的任何静态资源。
不需要额外新增私有路由,也不需要其他冗余配置,只需要调整中间件的执行顺序,加一层全局的认证校验即可。如果不想用session,也可以把认证后的令牌存在cookie里,校验逻辑完全一致。
内容的提问来源于stack exchange,提问作者RuntimeError
相关产品推荐
相关产品推荐

