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

如何在Laravel中主动使CSRF Token过期(单次提交限制)

Laravel实现AJAX表单单次提交并主动过期CSRF Token

要实现表单仅允许AJAX单次提交、提交后立即失效当前CSRF Token,且页面刷新后可重新获取有效Token循环使用,可按以下步骤操作:

后端处理:提交后强制刷新CSRF Token

Laravel的CSRF Token存储在会话(session)中,默认键为_token。在处理AJAX提交的控制器方法里,完成业务逻辑后调用regenerateToken()方法即可让当前Token立即失效,同时生成新的Token。

示例控制器代码:

public function handleFormSubmit(Request $request)
{
    // 先做表单验证
    $validatedData = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|email',
        // 其他字段验证规则
    ]);

    // 执行表单提交的业务逻辑(比如写入数据库、发送邮件等)
    // ...

    // 重新生成CSRF Token,使旧Token彻底失效
    $request->session()->regenerateToken();

    // 返回成功响应
    return response()->json([
        'success' => true,
        'message' => '提交成功'
    ]);
}

regenerateToken()是Laravel内置方法,会直接替换会话中的Token值,后续用旧Token提交的请求会触发419状态码(页面过期),从根源阻止重复提交。

前端处理:防止重复点击+处理Token失效场景

前端需要做两件事:一是避免用户在提交过程中重复点击按钮;二是捕获后端返回的Token失效错误,给用户明确提示。

示例HTML表单:

<form id="oneTimeForm">
    @csrf <!-- Laravel自动生成的CSRF Token隐藏字段 -->
    <div>
        <label>姓名</label>
        <input type="text" name="name" required>
    </div>
    <div>
        <label>邮箱</label>
        <input type="email" name="email" required>
    </div>
    <button type="submit" id="submitBtn">提交表单</button>
</form>

示例JS代码(以jQuery为例,原生JS逻辑一致):

$(function() {
    let isSubmitting = false;

    $('#oneTimeForm').on('submit', function(e) {
        e.preventDefault();
        
        // 阻止重复提交请求
        if (isSubmitting) return;
        
        isSubmitting = true;
        $('#submitBtn').attr('disabled', true).text('提交中...');

        const formData = $(this).serialize();

        $.ajax({
            url: '/submit-form', // 替换为你的实际路由
            method: 'POST',
            data: formData,
            success: function(res) {
                alert(res.message);
                // 可选:重置表单,但此时旧Token已失效,无法再次提交
                $('#oneTimeForm')[0].reset();
            },
            error: function(xhr) {
                if (xhr.status === 419) {
                    alert('该表单已提交,请勿重复操作');
                } else {
                    alert('提交失败,请稍后重试');
                }
                // Token失效后,按钮保持禁用状态,提示用户刷新页面
                $('#submitBtn').text('提交已失效,请刷新页面');
            }
        });
    });
});

核心逻辑说明

  • 页面刷新后,Laravel会通过@csrf指令自动输出新的有效Token,用户可再次发起单次提交,形成循环。
  • 即使用户绕过前端的按钮禁用(比如通过控制台手动发起请求),后端的Token失效机制也会拦截重复提交,保证安全性。

可选优化:无刷新更新Token(无需页面刷新即可再次提交)

如果需要用户在不刷新页面的情况下也能再次提交,可以在后端响应中返回新生成的Token,前端同步更新表单中的Token字段:

后端修改响应:

return response()->json([
    'success' => true,
    'message' => '提交成功',
    'new_token' => csrf_token() // 返回新的Token
]);

前端success回调添加更新逻辑:

success: function(res) {
    alert(res.message);
    $('#oneTimeForm')[0].reset();
    // 更新表单中的CSRF Token
    $('#oneTimeForm input[name="_token"]').val(res.new_token);
    // 恢复按钮状态,允许再次提交
    isSubmitting = false;
    $('#submitBtn').attr('disabled', false).text('提交表单');
}

这样每次提交后都会更新Token,依然保持单次提交的限制,同时支持无刷新重复提交。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:10:28