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

使用React+Django DRF会话认证时如何将未认证用户重定向到登录页

问题核心说明

HTTPOnly类型的Cookie是浏览器的安全设计,禁止前端JavaScript读取,没有任何方法可以绕过这个限制,你原先直接读取sessionid的实现思路不可行,需要换其他方案

可行实现方案

方案1:后端提供鉴权校验接口(最安全,推荐)

这个方案完全依赖后端的真实会话校验,不会被前端篡改,是最稳妥的实现方式:

  • Django 侧新增一个轻量校验接口,示例代码如下:
# views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status

@api_view(['GET'])
def check_auth(request):
    if request.user.is_authenticated:
        return Response({"is_authenticated": True}, status=status.HTTP_200_OK)
    return Response({"is_authenticated": False}, status=status.HTTP_401_UNAUTHORIZED)

然后在urls.py里注册这个接口路由为/api/auth/check

  • React 侧封装全局路由守卫组件,所有需要登录的路由都用该组件包裹,示例如下:
import { Navigate } from 'react-router-dom'
import { useEffect, useState } from 'react'
import axios from 'axios'

const AuthRoute = ({ children }) => {
  const [authStatus, setAuthStatus] = useState('loading')

  useEffect(() => {
    const verifyAuth = async () => {
      try {
        // 必须开启withCredentials,请求才会自动携带sessionid Cookie
        await axios.get('/api/auth/check', { withCredentials: true })
        setAuthStatus('authed')
      } catch (err) {
        if (err.response?.status === 401) {
          setAuthStatus('unauthed')
        }
      }
    }
    verifyAuth()
  }, [])

  if (authStatus === 'loading') return <div>加载中...</div>
  return authStatus === 'authed' ? children : <Navigate to="/login" replace />
}

// 路由配置中使用
<Route path="/user/center" element={
  <AuthRoute>
    <UserCenter />
  </AuthRoute>
} />

方案2:登录成功后额外下发普通标记Cookie(实现更简单)

这个方案适合对跳转逻辑性能要求高、不想多发起一次校验请求的场景:

  • 登录接口校验通过下发sessionid的同时,额外设置一个非HTTPOnly的普通Cookie,比如命名为has_login,过期时间和sessionid完全一致,值可以随便填,比如设为1
  • 前端直接读取has_login的Cookie值判断是否需要跳转,注意:这个判断仅用来做前端路由跳转的依据,所有后端接口必须保留原生的session校验逻辑,因为该Cookie可以被用户手动篡改

兜底方案:全局请求响应拦截

配合上面任意方案使用,避免用户在页面停留期间会话过期没触发跳转的问题:

// axios全局配置
axios.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      // 清除本地可能存在的登录标记,跳转到登录页
      window.location.href = '/login'
    }
    return Promise.reject(error)
  }
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 03:42:01