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

如何在React JS中使用dj-rest-auth实现Google社交认证

基于dj-rest-auth的谷歌社交登录React实现方案

前置准备

  • 确保Django后端的dj-rest-auth、social-auth-app-django配置完全无误,谷歌云控制台的OAuth同意屏幕、授权重定向URI已经修改为你的React应用地址,例如http://localhost:3000/oauth/callback/google
  • React端推荐使用@react-oauth/google库处理谷歌OAuth流程,安装命令:npm install @react-oauth/google
  • 注意:谷歌云控制台的授权重定向URI必须和你React应用的域名、端口完全匹配,否则会触发授权错误

核心环节:code/access_token获取实现

原Nuxt教程的本质是走谷歌OAuth2授权流程,React端逻辑完全一致,仅调用方式有差异,以下提供两种常用实现方案:

方案1:授权码模式(获取code,安全性更高,推荐)

该模式和原教程Nuxt端的授权逻辑完全对齐,首先在应用根组件包裹谷歌授权提供者:

import { GoogleOAuthProvider } from '@react-oauth/google';

function App() {
  return (
    <GoogleOAuthProvider clientId="你在谷歌云控制台申请的客户端ID">
      {/* 应用其余组件 */}
      <LoginPage />
    </GoogleOAuthProvider>
  );
}

登录页组件代码示例:

import { useGoogleLogin } from '@react-oauth/google';
import axios from 'axios';

const LoginPage = () => {
  const googleLogin = useGoogleLogin({
    flow: 'auth-code', // 指定走授权码模式,返回授权code
    onSuccess: async (codeResponse) => {
      // codeResponse.code即为所需的授权码
      console.log('谷歌返回的授权码:', codeResponse.code);
      // 把code传给Django后端dj-rest-auth的谷歌登录接口
      try {
        const res = await axios.post('你的Django服务地址/dj-rest-auth/google/', {
          code: codeResponse.code
        });
        // 后端返回的JWT令牌存入本地存储或状态管理工具
        localStorage.setItem('access_token', res.data.access);
        localStorage.setItem('refresh_token', res.data.refresh);
      } catch (err) {
        console.error('登录请求失败', err);
      }
    },
    onError: (error) => console.log('谷歌授权失败', error)
  });

  return (
    <button onClick={() => googleLogin()}>
      使用谷歌账号登录
    </button>
  );
};

export default LoginPage;

方案2:隐式模式(直接获取access_token)

如果你的业务场景适合用隐式授权模式,仅需修改useGoogleLogin的配置参数即可:

const googleLogin = useGoogleLogin({
  flow: 'implicit', // 指定隐式模式,直接返回谷歌侧的access_token
  onSuccess: async (tokenResponse) => {
    // tokenResponse.access_token即为所需的访问令牌
    console.log('谷歌返回的access_token:', tokenResponse.access_token);
    // 传给后端接口的逻辑和方案1完全一致,仅请求参数替换为access_token
    const res = await axios.post('你的Django服务地址/dj-rest-auth/google/', {
      access_token: tokenResponse.access_token
    });
    // 后续存令牌逻辑和方案1相同
  }
});

JWT令牌刷新实现

不需要依赖Nuxt的auth模块,React端可以通过封装axios拦截器实现自动刷新:

// 封装全局axios实例
import axios from 'axios';

const api = axios.create({
  baseURL: '你的Django后端服务地址'
});

// 请求拦截器:自动携带access_token
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('access_token');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 响应拦截器:access_token过期自动用refresh_token刷新
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;
    // 判定401状态且未重试过的请求自动刷新令牌
    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      const refreshToken = localStorage.getItem('refresh_token');
      try {
        const res = await axios.post('你的Django服务地址/dj-rest-auth/token/refresh/', {
          refresh: refreshToken
        });
        localStorage.setItem('access_token', res.data.access);
        // 重新发起原请求
        return api(originalRequest);
      } catch (err) {
        // refresh_token也过期,清空本地存储跳转登录页
        localStorage.clear();
        window.location.href = '/login';
      }
    }
    return Promise.reject(error);
  }
);

export default api;

内容的提问来源于stack exchange,提问作者Jonathan Aplacador

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:39:03