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

Django+HTMX社交加好友系统CSRF Token无效致403错误求助

Django + HTMX 好友系统 403 Forbidden(无效CSRF Token)问题解决方案

核心问题分析

Django的CSRF保护机制要求所有POST请求必须携带有效CSRF Token,你的代码中虽尝试通过hx-headers传递Token,但存在局部模板Token渲染失效、请求未覆盖目标UI更新、冗余Token设置等问题,导致Token验证失败触发403错误。

具体修复步骤

1. 全局配置HTMX自动携带CSRF Token

避免每个按钮重复编写hx-headers,同时解决局部模板无法获取csrf_token的问题:
在base.html的<body>末尾添加以下脚本,并确保页面包含CSRF Token字段:

<!-- 在base.html中添加CSRF隐藏字段 -->
{% csrf_token %}

<!-- HTMX全局配置:自动携带CSRF Token -->
<script>
document.body.addEventListener('htmx:configRequest', (event) => {
  event.detail.headers['X-CSRFToken'] = document.querySelector('[name=csrfmiddlewaretoken]').value;
});
</script>

添加后,所有HTMX POST请求会自动携带有效Token,无需在按钮上单独设置hx-headers。

2. 修复sent_requests.html中的变量错误

模板中按钮的id使用了未定义的user变量,导致渲染异常,修改为:

<button
  id="cancel-{{ request.requests_user.username }}"
  hx-post="{% url 'cancel_request' request.pk %}"
  hx-trigger="click"
  hx-target="#sent-requests"
  hx-swap="innerHTML"
  class="p-3 bg-red-100 hover:bg-red-200 rounded-lg text-red-800 font-bold flex gap-2 items-center"
>
  <i class="fa-solid fa-xmark text-lg"></i> Cancel Request
</button>

3. 修复add_friend视图的UI更新逻辑

当前视图仅更新已发送请求列表,未实现“添加好友后移除对应用户”的需求,使用HTMX的OOB(Out of Band)交换同时更新两个区域:

def add_friend(request, username):
    user_to_request = User.objects.get(username=username)
    # 创建好友请求
    Friend.objects.create(user=request.user, requests_user=user_to_request)
    # 获取最新的已发送请求和无关系用户列表
    sent_requests = Friend.objects.filter(user=request.user, request_accepted=False)
    users = get_users_no_rel(request.user)

    # 生成两个区域的HTML内容
    add_friend_html = render_to_string(
        'base/partials/add_friends.html', 
        {'user_list': users},
        request=request  # 确保模板能获取上下文
    )
    sent_requests_html = render_to_string(
        "base/partials/sent_requests.html", 
        {'sent_requests': sent_requests},
        request=request
    )

    # 组合OOB响应,同时更新#sent-requests和#add区域
    response_html = f"""
    {sent_requests_html}
    <div id="add" hx-swap-oob="outerHTML">{add_friend_html}</div>
    """
    return HttpResponse(response_html)

4. 移除冗余的Token设置

cancel_request视图中手动设置X-CSRFToken响应头是多余的,Django会自动管理CSRF Cookie,删除以下代码:

# response['X-CSRFToken'] = get_token(request)  # 移除该行

验证步骤

  1. 打开浏览器开发者工具的Network标签;
  2. 触发添加/取消好友请求,检查POST请求的Headers中是否包含X-CSRFToken字段,且值与页面中csrfmiddlewaretoken隐藏字段一致;
  3. 确认操作后,#add区域的用户列表和#sent-requests区域的请求列表均正确更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:54:51