使用fastify-oauth2+React实现GitHub OAuth时Axios调用遇CORS错误
GitHub OAuth授权跨域问题排查与解决
问题现象
使用fastify-oauth2结合React实现GitHub OAuth授权时,通过React应用的Axios调用授权接口出现跨域错误,但直接用window.location.assign跳转到授权接口则能正常完成流程。
错误信息
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://github.com/login/oauth/authorize?response_type=code&client_id=<client_id>&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Foauth2%2Fgithub%2Fcallback&scope=user&state=
. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 404.
相关配置
fastify-oauth2配置
const oAuthOptions: FastifyOAuth2Options = { name: "githubOAuth2", scope: ["user"], credentials: { client: { id: "<CLIENT_ID>", secret: "<CLIENT_SECRET>", }, auth: oAuth2Plugin.GITHUB_CONFIGURATION, }, startRedirectPath: "/oauth2/github/login", callbackUri: "http://localhost:4000/oauth2/github/callback", };
回调路由
app.get( "/github/callback", async (req: FastifyRequest, reply: FastifyReply) => { try { const { token } = await app.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(req); console.log({ userAuthToken }, "Authenticated successfully!"); reply.send({ token }); } catch (error) { reply.code(500).send("Failed to authenticate"); } } );
CORS配置
const corsOptions: FastifyCorsOptions = { origin: "*", // ["https://github.com", "http://localhost:5173"], credentials: true, // allowedHeaders: [ // "Access-Control-Allow-Origin", // "Access-Control-Allow-Headers", // "Origin, X-Requested-With, Content-Type, Accept", // ], };
React调用代码
const handleOAuth = async () => { try { const response = await axios.get("http://localhost:4000/oauth2/github/login"); console.log(response.data); history("/user"); } catch (error) { console.error(error); } };
原因分析
- OAuth授权流程本质是浏览器跳转:fastify-oauth2的
/oauth2/github/login接口会返回302重定向响应,引导浏览器跳转到GitHub授权页面。Axios发起的是AJAX请求,浏览器自动处理重定向后,GitHub的授权接口不会返回CORS允许头,因此触发跨域错误。 window.location.assign属于合法页面跳转:这种方式直接让浏览器发起页面跳转请求,不属于AJAX范畴,不会触发同源策略的跨域检查,因此能正常进入GitHub授权流程。- 回调路由路径不匹配:当前回调路由是
/github/callback,但callbackUri配置的是http://localhost:4000/oauth2/github/callback,路径不一致会导致授权后GitHub回调失败,进一步引发异常。 - CORS配置不合理:当启用
credentials: true时,origin: "*"是无效的,必须指定具体的前端域名(如http://localhost:5173)。
解决方案
1. 修正React触发授权的方式(核心解决)
放弃Axios请求,改用页面跳转触发授权,符合OAuth流程设计:
const handleOAuth = () => { window.location.assign("http://localhost:4000/oauth2/github/login"); };
或者直接用HTML链接:
<a href="http://localhost:4000/oauth2/github/login">GitHub登录</a>
2. 修正回调路由路径
确保路由路径与callbackUri一致:
app.get( "/oauth2/github/callback", // 修正为与callbackUri匹配的路径 async (req: FastifyRequest, reply: FastifyReply) => { try { const { token } = await app.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(req); console.log({ token }, "Authenticated successfully!"); // 授权完成后跳转到React的用户页面 reply.redirect("http://localhost:5173/user"); } catch (error) { reply.code(500).send("Failed to authenticate"); } } );
3. 优化CORS配置
指定前端域名,确保credentials生效:
const corsOptions: FastifyCorsOptions = { origin: "http://localhost:5173", // 开发环境地址,生产环境替换为实际域名 credentials: true, allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept"], };
内容的提问来源于stack exchange,提问作者VinayManala
相关产品推荐
相关产品推荐

