【发布时间】:2020-03-21 00:18:51
【问题描述】:
我正在尝试使用 Google OAuth 身份验证设置 React/Redux - NodeJs Express 堆栈。我的问题是控制台中出现的 COR 错误。我发现了一些我认为正是我的问题的 Stack Overflow 问题,但这些解决方案没有产生任何结果。特别是这两个:CORS with google oauth 和 CORS/CORB issue with React/Node/Express and google OAuth。
所以我尝试了各种修复方法,但似乎都让我回到了同样的错误。这是其中最直接的:
const corsOptions = {
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true
}
app.use(cors(corsOptions));
这是在我的API.js 文件的根目录中。我收到的控制台错误状态:
从源“null”访问“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.apps.googleusercontent.com”处的 XMLHttpRequest(从“http://localhost:5000/api/oauth/google”重定向)已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“访问控制” -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
所以在我看来,我的问题不在于我的前后沟通。这让我相信这可能是 Passport 令牌验证的问题。这是我的简化路线:
router.post('/oauth/google', passport.authenticate('googleVerification', {
scope: ['profile']
}), (req, res) => {
console.log('Passport has verified the oauth token...');
res.status(200)
});
以及回调路由:
router.get('/oauth/google/return', (req, res) => {
console.log('google oauth return has been reached...')
res.status(200)
});
最后,简化的策略:
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)
}));
我知道所有这些都不会导致任何功能,但我只是尽可能多地扯掉了绒毛,试图弄清楚我的身份验证流程中的块在哪里。以防万一它有助于缩小范围,这里是 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
})
}
};
这实际上从未到达返回,并且不会记录第二个console.log。
【问题讨论】:
-
问题中引用的错误消息表明您的前端 JavaScript 代码正在向
https://accounts.google.com/o/oauth2/v2/auth端点发出请求,并直接从该端点获得响应。但是由于该端点故意不包含 Access-Control-Allow-Origin 响应标头,因此您的浏览器会阻止您的前端代码访问响应。该端点并不意味着从代码中调用。相反,用户应该被导航到那里,然后重定向回您的应用程序。见stackoverflow.com/a/43276710等。 -
根据问题中的代码 sn-ps ,我猜您可能正在尝试通过后端代理请求。但如果是这样,那不是正在发生的事情。相反,来自您的前端代码的请求似乎只是被重定向(未代理)到
https://accounts.google.com/o/oauth2/v2/authURL。无论如何,该 URL 唯一应该发生的事情是用户被导航到它,手动登录,然后将他们重定向回您的应用程序。 -
@sideshowbarker 非常感谢您的回复。这就是我怀疑的问题,但是尽管搜索了几天,我还是找不到关于流程应该如何工作的明确解释。在我看来,如果您想使用 oauth 进行验证和受保护的路由,则必须通过服务器进行代理。我在 React 中使用 react-google-login 包。它发送用户登录,并返回一个用户对象(包括令牌)。我正在将该令牌发送到我的服务器,以使用 Passport 对照我的客户端密码验证它。
-
@sideshowbarker 如果我从保护
/oauth/google路由中删除 Passport,则该路由会收到一个请求,该请求的正文包含用户的访问令牌且没有错误。所以我不得不假设 Passport 正在向https://accounts.google.com/o/oauth2/v2/auth发出请求,这导致了错误。对于我的生活,我找不到这种流程的直接工作示例。这让我感到困惑,因为 React、Node、Express、Passport 似乎都是行业标准。
标签: node.js express oauth-2.0 cors passport.js