You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express部署Azure后React非首页路由报401未授权问题

Azure部署后React路由页面401未授权问题排查

我有一个同项目下的Node.js Express后端(本地5000端口)和ReactJS前端(本地3000端口)项目。本地通过npm start启动客户端、nodemon index.js启动服务端可正常运行,执行npm run build后在http://localhost:3000也能正常访问生产构建的静态文件。

但通过VS Code的Azure App Services扩展发布到Azure后,用户能正常登录认证,仅首页可正常访问,访问其他页面时出现401未授权错误,原因未知。


项目文件结构

- MyApp:
  - .vscode
  - Client:
     - build
        - static
           - css
           - js
        - index.html
     - node_modules
     - public
     - src
     - package.json
     - package-lock.json
  - config
  - controllers
  - middleware
  - models
  - index.js
  - package.json
  - package-lock.json

客户端路由(Client-->src-->App.js)

function App() {
  return (
    <Routes>
      
      <Route path="/" element={<Layout />}>
        {/* Public routes*/}
        <Route exact path='Login' element={<Login/>}  />
        <Route path="unauthorized" element={<Unauthorized />} />
        <Route path="invalidinvite" element={<InvalidInvite />} />
        <Route path='Application' element={<Application />}  />
        

        {/* Protected routes*/}

        <Route element={ <PersistLogin /> }>
          <Route element={<RequireAuth allowedRoles={[1, 2]}/>}> 
            <Route exact path="/" element={<Invite/>} />
          </Route>

          <Route element={<RequireAuth allowedRoles={[1, 2]}/>}> 
            <Route exact path='Submitted' element={<Submitted/>} />
          </Route>

          <Route element={<RequireAuth allowedRoles={[1, 3]}/>}> 
            <Route exact path='Approved' element={<Approved/>} />
          </Route>
        </Route>

        {/* Catch all*/}
        <Route path="*" element={Error} />
      </Route>
    </Routes>
  );
}

客户端入口文件(Client-->src-->index.js)

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter>
      <AuthProvider>
        <Routes>
          <Route path="/*" element={<App />} />
        </Routes>
      </AuthProvider>
    </BrowserRouter>
  </React.StrictMode>
);

服务端入口文件(index.js)

require('dotenv').config();
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const cors = require('cors');

const sequelize = require("./config/database");

const verifyJWT = require('./middleware/verifyJWT');
const cookieParser = require('cookie-parser');
const credentials = require('./middleware/credentials');
const corsOptions = require('./config/corsOptions');

const PORT = process.env.PORT || 5000;


//Applying middleware
app.use(credentials); //Handle options credentials check before CORS and fetch cookies credential requirement
app.use(cors(corsOptions)); //Cross origin resource sharing
app.use(express.json()); 
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());

app.use(express.static(path.join(__dirname, 'client', 'build')));

//public routes
app.use('/auth', require('./routes/authRoutes'))
app.use('/postInviteId', require('./routes/postInviteId'))
app.use('/invites/:Id', require('./routes/inviteById'))
app.use('/application', require('./routes/postApplication'))

app.use(verifyJWT); //Anything below this has to have a verified JWT

//private routes
app.use('/invites', require('./routes/invites'))
app.use('/email', require('./routes/emails'))
app.use('/application', require('./routes/applications'))


app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, 'client', 'build', 'index.html'));
});

sequelize.sync().then(() => {
}).catch((err) => {
  console.log(err);
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

环境Network截图

生产环境下访问其他页面的Network标签截图:
生产环境Network截图

本地环境下访问其他页面的Network标签截图:
本地环境Network截图


解决思路

  1. 检查JWT Cookie的生产环境配置

    • Azure App Service默认用HTTPS,需确保JWT Cookie开启secure: true,否则无法在HTTPS环境下传递;sameSite建议设为'Lax'或'None'(设为None必须同时开启secure),避免跨站点请求时Cookie被拦截。
    • 对比本地和生产环境的Cookie设置,排查是否遗漏必要属性。
  2. 验证verifyJWT中间件的路径匹配

    • 确认verifyJWT只作用于API路由,而非前端路由的静态文件返回请求。检查app.use(verifyJWT)的位置是否在静态资源和前端兜底路由之前,避免误拦截React路由的index.html返回请求。
  3. 适配CORS的生产环境配置

    • 查看corsOptions,确保已将Azure的实际域名加入允许列表,且credentials: true已正确设置,保证Cookie能跨域传递(本地开发时可能只允许localhost:3000,生产环境需替换为Azure域名)。
  4. 排查PersistLogin组件逻辑

    • 检查PersistLogin在生产环境下是否正确读取并发送JWT(从Cookie或localStorage),对比本地和生产环境请求头的Cookie/Authorization字段,确认认证令牌是否被正确携带。
  5. 配置Azure App Service的SPA路由支持

    • 对于React单页应用,需在Azure上配置路由转发:Windows环境添加web.config,Linux环境添加.htaccess,确保所有路由请求都转发到index.html,避免Azure直接返回404或错误拦截。
    • 检查Azure应用设置中的WEBSITE_NODE_DEFAULT_VERSION,确保Node.js版本与本地一致。

内容的提问来源于stack exchange,提问作者It hurts when IP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:25:14