如何解决我的 MERN 应用程序中的 Access-Control-Allow-Origin CORS 错误以进行 MSAL 身份验证?
Posted
技术标签:
【中文标题】如何解决我的 MERN 应用程序中的 Access-Control-Allow-Origin CORS 错误以进行 MSAL 身份验证?【英文标题】:How can I solve the Access-Control-Allow-Origin CORS error in my MERN app for MSAL auth? 【发布时间】:2021-07-15 15:38:43 【问题描述】:我正在尝试通过单击按钮在我的 MERN 应用中通过 MSAL 进行身份验证。
但是我得到了这个错误:
访问 XMLHttpRequest 在 'https://login.microsoftonline.com/common/oauth2/v2.0/a...' (重定向自 'http://
/api/auth/signin') 'http:// ' 已被 CORS 策略阻止:否 请求中存在“Access-Control-Allow-Origin”标头 资源。
这是我的 NodeJS 服务器的代码:
const express = require("express");
const session = require('express-session');
const authRoutes = require("./routes/auth.routes");
const msal = require('@azure/msal-node');
const cors = require("cors");
require("dotenv").config();
const app = express();
const corsOptions =
origin : process.env.CLIENT_URL,
credentials: true,
"allowedHeaders": ["sessionId", "Content-Type"],
"exposedHeaders": ["sessionId"],
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false
app.use(cors(corsOptions));
// Demo only
app.locals.users = ;
// MSAL Config
const msalConfig =
auth:
clientId: process.env.OAUTH_APP_ID,
authority: process.env.OAUTH_AUTHORITY,
clientSecret: process.env.OAUTH_APP_SECRET
,
system:
loggerOptions:
loggerCallback(loglevel, message, containsPii)
console.log(message);
,
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
;
app.locals.msalClient = new msal.ConfidentialClientApplication(msalConfig);
// Session middleware
app.use(session(
secret: 'your_secret_value_here',
resave: false,
saveUninitialized: false,
unset: 'destroy'
));
app.use("/api/auth", authRoutes);
app.get("/", (req, res) =>
res.send("Hello World!");
);
app.listen(process.env.PORT, () =>
console.log(`Server is running on port $process.env.PORT`);
);
module.exports = app;
这是我的 auth.controller 方法:
module.exports =
signIn: async (req, res) =>
const urlParameters =
scopes: process.env.OAUTH_SCOPES.split(','),
redirectUri: process.env.OAUTH_REDIRECT_URI
;
try
const authUrl = await req.app.locals.msalClient.getAuthCodeUrl(urlParameters);
res.redirect(authUrl);
catch (error)
console.log(`Error: $error`);
res.redirect("/");
,
callback: async (req, res) =>
const tokenRequest =
code: req.query.code,
scopes: process.env.OAUTH_SCOPES.split(","),
redirectUri: process.env.OAUTH_REDIRECT_URI
;
try
const response = await req.app.locals.msalClient.acquireTokenByCode(tokenRequest);
req.session.userId = response.account.homeAccountId;
const user = await graph.getUserDetails(response.accessToken);
req.app.locals.users[req.session.userId] =
displayName: user.displayName,
email: user.mail || user.userPrincipalName,
timeZone: user.mailboxSettings.timeZone
;
catch (error)
console.log(`Error: $error`);
res.redirect("/");
,
signOut: async (req, res) =>
if (req.session.userId)
const accounts = await req.app.locals.msalClient.getTokenCache().getAllAccounts();
const userAccount = accounts.find(a => a.homeAccountId === req.session.userId);
if (userAccount)
req.app.locals.msalClient.getTokenCache().removeAccount(userAccount);
req.session.destroy(err => res.redirect("/"));
;
这里是 React 部分:
import React from 'react';
import axios from "axios";
const App = () =>
const handleConnect = () =>
axios(
method: "get",
url: `$process.env.SERVER_URL/api/auth/signin`,
withCredentials: true
)
.then(res => console.log(res.data))
.catch(err => console.log(err));
;
return (
<button onClick=handleConnect>Connect</button>
);
;
export default App;
在我的 Azure Active Directory 管理中心,我的重定向 URI 是:
“”作为“SPA” “/api/auth/signin”为“Web”
【问题讨论】:
【参考方案1】:devtools 中的 Network 选项卡有助于解决此类问题。
您可能需要处理 CORS preflight requests,通过在您的 express 应用中放置类似的内容来处理 OPTIONS 请求。
app.options('*',cors())
将此行放在app.use()
之前用于任何路线。
这在生产中有点我。哎哟!
【讨论】:
感谢您的回答,但我仍然收到相同的 CORS 错误。我需要摆脱 app.use(cors(corsOptions)) 吗? 如果您完全摆脱 CORS,您的错误应该会消失。查看浏览器开发工具的网络选项卡,了解预检请求发生了什么。 如果您使用credentials:true
并允许所有来源 *
,我不确定它是否有效。
我从我的应用程序中删除了 cors,但我仍然收到错误,但这次来自 将Access-Control-Allow-Origin
设置为*
风险很大,不推荐。这意味着您允许任何来源从您的服务器接收响应。
删除 CORS 意味着将执行同源策略,因此它将不起作用。
要解决客户端和服务器之间的问题,您可以在 React 应用程序的 package.json
文件中设置一个代理,该代理将指向您的服务器:"proxy": "YourServerURI"
。
关于 MSAL 错误的最初问题,我建议仔细检查您的应用是否已正确注册并有权访问您的服务器。
【讨论】:
谢谢,代理解决了客户端和服务器之间的问题,现在我很苦恼,因为我认为我在 Azure AD 中设置了错误的重定向 URI... 您阅读过Node.js - MSAL Quickstart 指南吗?应该很简单。重定向 URI 必须是客户端应用程序中的路径。根据文档,它应该是http://localhost:3000/redirect
以上是关于如何解决我的 MERN 应用程序中的 Access-Control-Allow-Origin CORS 错误以进行 MSAL 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 NodeJS 中的这个 no-unused-vars 错误?
获取“被 CORS 策略阻止:请求的资源上不存在 'Access-Control-Allow-Origin' 标头。”使用 Axios 使用 MERN 堆栈