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

React OAuth2 Google登录请求报错:凭证无效问题排查

React + DRF 社交登录适配 react-oauth2/google 报错问题

我在为React网站集成社交登录功能,后端采用DRF框架。原使用的react-google-login已弃用,转而使用react-oauth2/google库。之前react-google-login会直接返回access_token和refresh_token,可直接传给Django端(基于social_django)进行用户数据校验与令牌请求;但react-oauth2/google仅返回code,将该code传给后端时,收到"wrong credential"错误。


原代码片段

Auth.js

const GoogleLoginFunc = useGoogleLogin({
        flow: 'auth-code',
        onSuccess: async (codeResponse) => {
            console.log(codeResponse);
            
            // const tokens = await axios.post(
            //     'http://localhost:3000/auth/google', {
            //         code: codeResponse.code,
            //     });

            // console.log(tokens);
            SocialGoogleLoginFunc(codeResponse.code)
        },
        onError: errorResponse => console.log(errorResponse),
    });


<GoogleLogin
                            
                            onSuccess={GoogleLoginFunc}

                            // onSuccess={credentialResponse => {
                            //     console.log(credentialResponse.credential);
                            //     SocialGoogleLoginFunc(credentialResponse.credential)
                            //   }}

                            onError={() => {
                                console.log('Login Failed');
                            }}

                            useOneTap
                            />

GoogleAuth.js

const SocialGoogleLoginFunc=(accesstoken,app_id,app_secret)=>{
// console.log(`MY CREDENTIALS ${app_id},${app_secret}`)
// let client_id='nILBGJCOSiaLKDyRZeFpHmUoyDw0PgChrkEGzjkj'
// let client_secret='fkUSbr5mtR6oIX3osX51zS1ycbWOfNWGvEjhhKwVQvBb3rJ8gRN1BW2gkFMiPBfBKq3437IC3joXQUEFxPRs1PSXfSgKehOCwoRJoNgjtAzI6ZXwdjyX3RyZfTKKb8hE'

// console.log(client_secret.includes(' '))
// http://127.0.0.1:8000/client/auth/convert-token
// grant_type:"convert_token",
// client_id: client_id,
// client_secret: client_secret,
// backend:"google-oauth2", 
// token:accesstoken
// http://127.0.0.1:8000/
fetch('http://127.0.0.1:8000/auth/api/register-by-access-token/social/google-oauth2/',{
   
    method: "POST",
    body: JSON.stringify({
        
        access_token:accesstoken

    }),
    headers: {
        "Content-Type": 'application/json;charset',
        "accept":'application/json;charset'

    }

})
.then(response=>{
    return response.json()
}).then(data=>{
   try{
    console.log(data)
    localStorage.setItem('access_token',data.access_token)
    localStorage.setItem('refresh_token',data.refresh_token)
   }catch(error){
    console.log(error)
   }

})

export default SocialGoogleLoginFunc


问题原因与修复方案

核心问题

react-oauth2/google的auth-code流程返回的authorization code,和react-google-login返回的access token是完全不同的凭证。你当前把code当作access_token传给后端,后端无法识别,因此抛出"wrong credential"错误。

修复步骤

方案1:前端用code换取Google官方access_token

拿到authorization code后,先调用Google的令牌接口将code转换为真正的access_token,再传给后端:

const GoogleLoginFunc = useGoogleLogin({
  flow: 'auth-code',
  clientId: '你的Google客户端ID', // 需与Google开发者控制台配置一致
  onSuccess: async (codeResponse) => {
    try {
      // 向Google换取access_token
      const googleTokenRes = await fetch('https://oauth2.googleapis.com/token', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: new URLSearchParams({
          code: codeResponse.code,
          client_id: '你的Google客户端ID',
          client_secret: '你的Google客户端密钥',
          redirect_uri: 'postmessage', // 前端单页应用固定值
          grant_type: 'authorization_code',
        }),
      });

      const googleTokenData = await googleTokenRes.json();
      // 将真实的access_token传给后端
      await SocialGoogleLoginFunc(googleTokenData.access_token);
    } catch (error) {
      console.error('换取Google令牌失败:', error);
    }
  },
  onError: errorResponse => console.log('登录失败:', errorResponse),
});

方案2:切换到implicit flow直接获取access_token

如果不需要refresh_token,可以将登录流程改为implicit,直接获取access_token,与原react-google-login行为一致:

const GoogleLoginFunc = useGoogleLogin({
  flow: 'implicit',
  onSuccess: (response) => {
    // 直接拿到access_token
    SocialGoogleLoginFunc(response.access_token);
  },
  onError: () => console.log('登录失败'),
  useOneTap: true
});

内容的提问来源于stack exchange,提问作者miracle godwin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:30:53