Dal*_*eri 2 node.js cors oauth-2.0 express passport.js
我正在尝试使用 Google OAuth 身份验证设置 React/Redux - NodeJs Express 堆栈。我的问题是控制台中的 COR 错误。我发现了一些我认为正是我的问题的 Stack Overflow 问题,但解决方案没有产生任何结果。特别是这两个:CORS与谷歌的OAuth和CORS / CORB问题与之反应/节点/ Express和谷歌的OAuth。
因此,我尝试了各种修复方法,这些修复方法似乎都使我回到了相同的错误。这是其中最直接的:
const corsOptions = {
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true
}
app.use(cors(corsOptions));
Run Code Online (Sandbox Code Playgroud)
这是在我的API.js文件的根目录中。我收到的控制台错误状态:
访问 XMLHttpRequest ' https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fapi%2Foauth%2Fgoogle%2Freturn&scope=profile&client_id=PRIVATE_CLIENT_ID。 .googleusercontent.com '(重定向自 ' http://localhost:5000/api/oauth/google ')来自原点 'null' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否 '请求的资源上存在 Access-Control-Allow-Origin 标头。
因此,如果我在开发工具中查看我的网络日志,我会查看我对 API 路径的请求,并查看我希望看到的内容:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: http://localhost:3000
Run Code Online (Sandbox Code Playgroud)
所以在我看来,我的问题不在于我的前后沟通。这让我相信这可能是 Passport 令牌验证的问题。以下是我的简化路线:
router.post('/oauth/google', passport.authenticate('googleVerification', {
scope: ['profile']
}), (req, res) => {
console.log('Passport has verified the oauth token...');
res.status(200)
});
Run Code Online (Sandbox Code Playgroud)
和回调路线:
router.get('/oauth/google/return', (req, res) => {
console.log('google oauth return has been reached...')
res.status(200)
});
Run Code Online (Sandbox Code Playgroud)
最后,简化策略:
passport.use('googleVerification', new GoogleStrategy({
clientID: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_SECRET,
callbackURL: 'http://localhost:5000/api/oauth/google/return'
}, (accessToken, refreshToken, profile, cb) => {
console.log('Passport OAuth Strategy reached');
cb(null, profile)
}));
Run Code Online (Sandbox Code Playgroud)
我知道所有这些都不会导致任何功能,但我只是尽可能多地撕掉了绒毛,试图了解我的身份验证流程中的块在哪里。以防万一它可能有助于缩小范围,这里是 Redux 中的动作创建者,它在错误开始出现之前记录过程中的最后一步('redux 接受令牌并传递给 API:',令牌):
export const signIn = (token) => {
console.log('redux accepting token and passing to API:', token)
return async dispatch => {
const res = await Axios({
method: 'post',
url: `${API_ROOT}/api/oauth/google`,
withCredentials: true,
data: {
access_token: token
}
})
console.log('API has returned a response to redux:', res)
dispatch({
type: SIGN_IN,
payload: res
})
}
};
Run Code Online (Sandbox Code Playgroud)
这实际上从未达到返回值,并且不会记录第二个console.log记录。
该 CORS 与向 google 提出请求无关,因为当您在console.developers.google.com 中注册您的应用程序时,它已经由 google 处理。
问题出在CRA 开发人员服务器和express api 服务器之间。您正在从localhost:3000向localhost:5000发出请求。要解决此问题,请使用代理。
在客户端目录中:
npm i http-proxy-middleware --save
Run Code Online (Sandbox Code Playgroud)
在client/src 中创建setupProxy.js文件。无需在任何地方导入它。create-react-app会寻找这个目录
将您的代理添加到此文件:
module.exports = function(app) {
app.use(proxy("/auth/google", { target: "http://localhost:5000" }));
app.use(proxy("/api/**", { target: "http://localhost:5000" }));
};
Run Code Online (Sandbox Code Playgroud)
我们是说创建一个代理,如果有人试图访问我们的反应服务器上的 /api 或 /auth/google 路由,自动将请求转发到localhost:5000。
这是更多详细信息的链接:
https://create-react-app.dev/docs/proxying-api-requests-in-development/
默认情况下,password.js 不允许代理请求。
passport.use('googleVerification', new GoogleStrategy({
clientID: process.env.OAUTH_CLIENT_ID,
clientSecret: process.env.OAUTH_SECRET,
callbackURL: 'http://localhost:5000/api/oauth/google/return',
proxy:true
}
Run Code Online (Sandbox Code Playgroud)
这里重要的一件事是,您应该了解为什么使用代理。据我了解,从你的代码来看,从浏览器中,你向 express 发出请求,express 将使用 password.js 处理身份验证。password.js 运行完所有认证步骤后,它会创建一个 cookie,用 id 填充它,将它交给 express,然后 express 将它发送到浏览器。这是您的应用程序结构:
BROWSER ==> EXPRESS ==> GOOGLE-SERVER
Run Code Online (Sandbox Code Playgroud)
浏览器会自动将 cookie 附加到发出 cookie 的服务器的每个请求中。因此浏览器知道哪个 cookie 属于哪个服务器,因此当它们向该服务器发出新请求时,它们会附加它。但是在您的应用程序结构中,浏览器并未与 GOOGLE-SERVER 对话。如果你没有使用代理,你会通过express从GOOGLE-SERVER获取cookie,但是由于你没有向GOOGLE-SERVER发出请求,所以cookie不会被使用,它不会被自动附加。这就是使用 cookie 的要点,浏览器会自动附加 cookie。通过设置代理,现在浏览器不知道GOOGLE-SERVER。据它所知,它正在向快递服务器发出请求。所以每次浏览器使用相同的端口请求表达时,它都会附加cookie。我希望这部分是清楚的。
现在 react 只与 express-server 通信。
BROWSER ==> EXPRESS
Run Code Online (Sandbox Code Playgroud)
由于 react 和 exress 不在同一个端口上,因此您会收到 cors 错误。
有2个解决方案。1 正在使用cors包。
它的设置非常简单
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors()) // use this before route handlers
Run Code Online (Sandbox Code Playgroud)
第二种解决方案是在路由处理程序之前手动设置中间件
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"OPTIONS, GET, POST, PUT, PATCH, DELETE"
);
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
next(); // dont forget this
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4313 次 |
| 最近记录: |