Next.js 14与Django集成JWT认证及用户内容展示技术咨询
基于Django + Next.js 14的JWT认证与用户内容展示问题解答
一、JWT存入Http-only Cookie及访问方式
1. 存入Http-only Cookie
你当前的注册API已实现基础的Cookie设置,可补充安全属性适配生产环境:
// app/api/signup/route.js export default async function handler(req, res) { if (req.method === 'POST') { try { const { email, password, confirm_password, phone_number } = req.body; // 替换为Django后端的完整API地址,例如http://localhost:8000/api/accounts/signup/ const backendResponse = await fetch('http://your-django-domain/api/accounts/signup/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password, confirm_password, phone_number }), }); const data = await backendResponse.json(); if (data.jwt) { // 补充安全属性,生产环境建议添加Secure(仅HTTPS环境生效) const cookieOptions = [ `token=${data.jwt}`, 'HttpOnly', 'Path=/', 'SameSite=Strict', process.env.NODE_ENV === 'production' && 'Secure' ].filter(Boolean).join('; '); res.setHeader('Set-Cookie', cookieOptions); res.status(200).json({ success: true }); } else { res.status(401).json({ success: false, error: 'Authentication failed' }); } } catch (error) { res.status(500).json({ success: false, error: 'Internal server error' }); } } else { res.setHeader('Allow', ['POST']); res.status(405).end(`Method ${req.method} Not Allowed`); } }
核心说明:
HttpOnly:禁止前端JavaScript读取Cookie,避免XSS攻击SameSite=Strict:限制Cookie仅在同站请求中携带,防范CSRF攻击Secure:仅在HTTPS环境下传递Cookie,生产环境必须启用
2. 访问Http-only Cookie
由于HttpOnly特性,前端客户端代码(use client组件)无法直接读取该Cookie,只能通过以下方式使用:
- 浏览器自动携带:Next.js向Django后端发起请求时,浏览器会自动将同域的Http-only Cookie附加到请求头中,无需手动处理
- 服务器端代码读取:在API路由、中间件、服务器组件中,可通过
request.cookies获取,例如你当前的中间件实现(需修正API地址):
import type { NextRequest } from 'next/server' export async function middleware(request: NextRequest) { const token = request.cookies.get('token')?.value; // 替换为Django后端的完整验证API地址 const validateResponse = await fetch('http://your-django-domain/api/accounts/signin/verify/', { headers: { Authorization: `Bearer ${token}` }, // 跨域场景需添加该配置,确保Cookie被携带 credentials: 'include' }); if (!validateResponse.ok) { return Response.redirect(new URL('/auth/login', request.url)); } if (token && !request.nextUrl.pathname.startsWith('/profile')) { return Response.redirect(new URL('/profile', request.url)); } if (!token && !request.nextUrl.pathname.startsWith('/auth')) { return Response.redirect(new URL('/auth/login', request.url)); } } export const config = { matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'], }
注意:若Django与Next.js跨域,需在Django中配置CORS允许携带凭证。
二、个人主页展示专属内容的用户参数获取
是的,需要获取用户标识(如userID、邮箱)来拉取专属内容,推荐两种实现方式:
1. 注册/登录成功时返回用户参数
修改Django的注册/登录API,在返回JWT的同时,将userID、邮箱等非敏感信息包含在响应体中,Next.js的注册API路由再将这些信息返回给前端:
// app/api/signup/route.js 修改部分 if (data.jwt) { // 设置Cookie... // 返回用户信息给前端 res.status(200).json({ success: true, userInfo: { userId: data.user_id, email: data.email } }); }
前端可将这些信息存入内存状态(如React Context、Zustand),用于后续请求个人内容时携带。
2. 访问个人主页时通过Token获取用户信息
更安全的方式是:前端访问个人主页时,Next.js服务器组件或API路由携带Cookie中的Token调用Django用户信息接口,Django验证Token后返回专属数据,再渲染页面:
// app/profile/page.js 服务器组件 async function ProfilePage() { const response = await fetch('http://your-django-domain/api/accounts/user-info/', { credentials: 'include' }); if (!response.ok) { redirect('/auth/login'); } const userData = await response.json(); return ( <div> <h1>个人主页</h1> <p>用户ID:{userData.id}</p> <p>邮箱:{userData.email}</p> {/* 渲染其他专属内容 */} </div> ); } export default ProfilePage;
这种方式无需前端存储用户信息,所有数据均通过后端验证后获取,安全性更高。
内容的提问来源于stack exchange,提问作者Narges Ghanbari
相关产品推荐
相关产品推荐

