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

基于Django、GraphQL JWT、ReactJS的安全认证实现问题咨询

实现方案分步指南

一、Django后端配置(GraphQL接口鉴权)

  • 如果你使用Graphene Django搭建GraphQL接口,先安装django-graphql-jwt依赖,在需要鉴权的Mutation、Query上添加@login_required装饰器,未携带有效token的请求会直接返回401状态码
  • 在Django中间件配置中加入JWT校验中间件,确保所有GraphQL请求优先校验请求头里的Authorization字段,校验不通过直接返回401响应

注意:Djangodjango-graphql-jwt默认的Authorization头前缀是JWT ,如果你自己修改了配置前缀,后续React端传的时候要和后端保持一致,否则会校验失败。不要把token放在请求体里传输,标准做法是放在请求头的Authorization字段,避免跨域或者缓存导致的token泄露问题

二、React端携带Token发送GraphQL请求

根据你使用的GraphQL客户端选择对应配置:

场景1:使用Apollo Client

初始化Apollo Client时配置请求拦截器,每次发请求前自动把token加入请求头:

import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';

const httpLink = createHttpLink({
  uri: '/graphql/', // 替换为你的Django GraphQL接口地址
});

const authLink = setContext((_, { headers }) => {
  // 从你存储token的位置(比如localStorage、状态管理工具)取出token
  const token = localStorage.getItem('jwtToken');
  return {
    headers: {
      ...headers,
      authorization: token ? `JWT ${token}` : "",
    }
  }
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache()
});

场景2:使用Relay或原生fetch发请求

封装通用的GraphQL请求方法,主动在请求头添加token:

const graphqlRequest = async (query, variables = {}) => {
  const token = localStorage.getItem('jwtToken');
  const res = await fetch('/graphql/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': token ? `JWT ${token}` : ''
    },
    body: JSON.stringify({ query, variables })
  })
  // 校验状态码,401直接跳转到未授权页面
  if (res.status === 401) {
    localStorage.removeItem('jwtToken');
    window.location.href = '/unauthorized';
  }
  return res.json()
}

三、React端路由鉴权(未登录/Token无效跳转)

  • 封装私有路由组件PrivateRoute,所有需要登录才能访问的页面(包括你的表单提交页)都用该组件包裹:
import { Navigate, Outlet } from 'react-router-dom';

const PrivateRoute = () => {
  const token = localStorage.getItem('jwtToken');
  // 可扩展添加token过期校验逻辑:存储token时同步存过期时间,此处判断是否过期
  const isTokenValid = !!token;
  return isTokenValid ? <Outlet /> : <Navigate to="/unauthorized" replace />;
};
  • 路由配置示例:
<Route path="/" element={<公开首页 />} />
<Route path="/unauthorized" element={<自定义未授权页面 />} />
{/* 以下路由都需要登录才能访问 */}
<Route element={<PrivateRoute />}>
  <Route path="/submit-form" element={<表单提交页 />} />
  {/* 其他需要鉴权的路由都放在此处 */}
</Route>
  • 全局错误拦截补充:如果使用Apollo Client,可添加错误链接统一捕获鉴权失败异常:
import { onError } from "@apollo/client/link/error";

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    graphQLErrors.forEach(({ extensions }) => {
      if (extensions?.code === 'UNAUTHENTICATED') {
        localStorage.removeItem('jwtToken');
        window.location.href = '/unauthorized';
      }
    })
  }
  if (networkError && networkError.statusCode === 401) {
    localStorage.removeItem('jwtToken');
    window.location.href = '/unauthorized';
  }
});
// 初始化Apollo Client时把errorLink加入链路
const client = new ApolloClient({
  link: errorLink.concat(authLink.concat(httpLink)),
  cache: new InMemoryCache()
});

四、表单提交逻辑校验

完成以上配置后,表单提交时直接调用封装好的GraphQL Mutation即可,不需要额外处理token,拦截器会自动携带,若token无效会直接触发跳转逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 08:36:06