You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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);
  }
};

原因分析

  1. OAuth授权流程本质是浏览器跳转:fastify-oauth2的/oauth2/github/login接口会返回302重定向响应,引导浏览器跳转到GitHub授权页面。Axios发起的是AJAX请求,浏览器自动处理重定向后,GitHub的授权接口不会返回CORS允许头,因此触发跨域错误。
  2. window.location.assign属于合法页面跳转:这种方式直接让浏览器发起页面跳转请求,不属于AJAX范畴,不会触发同源策略的跨域检查,因此能正常进入GitHub授权流程。
  3. 回调路由路径不匹配:当前回调路由是/github/callback,但callbackUri配置的是http://localhost:4000/oauth2/github/callback,路径不一致会导致授权后GitHub回调失败,进一步引发异常。
  4. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:03:14