React应用调用Passport.js+Node.js+Azure AD OAuth2认证接口求助
问题说明
我已经基于Passport.js、Node.js和Azure AD OAuth2实现了后端认证服务,现在想在React应用中调用该认证端点,但不清楚具体的实现逻辑。以下是我尝试的代码,希望得到帮助:
后端代码(app.js)
import express from 'express'; import dotenv from 'dotenv'; import cors from 'cors'; import passport from 'passport'; import AzureAdOAuth2Strategy from 'passport-azure-ad-oauth2'; import jwt from 'jsonwebtoken'; // 补充缺失的JWT依赖导入 import User from './models/User'; // 补充User模型导入(需根据实际路径调整) const app = express(); dotenv.config(); const Port = process.env.PORT || 3001; passport.use( new AzureAdOAuth2Strategy( { clientID: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, callbackURL: 'https://www.example.net/auth/azureadoauth2/callback', resource: process.env.RESOURCE, tenant: 'contoso.onmicrosoft.com', }, function (accessToken, refresh_token, params, profile, done) { var waadProfile = profile || jwt.decode(params.id_token, '', true); User.findOrCreate({ id: waadProfile.upn }, function (err, user) { done(err, user); }); } ) ); // 修正CORS中间件配置:允许React应用域名并开启会话凭证 app.use(cors({ origin: 'http://localhost:3000', // 替换为你的React应用实际域名 credentials: true })); // 初始化Passport并启用会话支持 app.use(passport.initialize()); app.use(passport.session()); // 序列化用户到会话 passport.serializeUser((user, done) => { done(null, user.id); }); // 从会话反序列化用户 passport.deserializeUser((id, done) => { User.findById(id, (err, user) => { done(err, user); }); }); // 认证路由 app.get('/auth/azureadoauth2', passport.authenticate('azure_ad_oauth2')); app.get( '/auth/azureadoauth2/callback', passport.authenticate('azure_ad_oauth2', { failureRedirect: '/login' }), function (req, res) { // 认证成功后重定向到React应用页面 res.redirect('http://localhost:3000/dashboard'); // 替换为你的React应用首页/仪表盘地址 } ); // 新增接口:供React获取当前登录用户信息 app.get('/api/user', (req, res) => { if (req.isAuthenticated()) { res.json(req.user); } else { res.status(401).json({ message: '未授权' }); } }); app.get('/', (req, res) => { res.send('App is running successfully'); }); app.listen(Port, () => { console.log(`Server is listening on ${Port}`); });
前端代码(Login.js)
function Login() { const handleLogin = () => { // OAuth2授权码流程需通过浏览器重定向到后端认证端点,无需fetch window.location.href = 'http://localhost:4000/auth/azureadoauth2'; }; return <button onClick={handleLogin}>登录(Azure AD)</button>; } export default Login;
关键修正说明
- 后端CORS配置:原代码
app.use(express(cors))用法错误,需直接调用cors()并指定允许的React域名,同时开启credentials以保持会话。 - Passport会话支持:必须添加
passport.initialize()、passport.session()以及序列化/反序列化逻辑,否则认证成功后无法在后续请求中识别用户。 - 缺失依赖补充:原代码使用了
jwt和User模型但未导入,需补充对应语句。 - 前端登录逻辑:用
fetch调用认证端点不符合OAuth2流程,应直接通过window.location.href跳转到后端认证路由,触发Azure AD的授权页面。 - 回调重定向调整:后端回调路由需将用户重定向回React应用,而不是后端自身的根路径。
内容的提问来源于stack exchange,提问作者saygas
相关产品推荐
相关产品推荐

