【问题标题】:Sending Ajax requests with Laravel使用 Laravel 发送 Ajax 请求
【发布时间】:2017-06-14 19:40:29
【问题描述】:

我正在尝试学习如何通过 ajax 请求传递 csrf 令牌(我正在使用 Laravel),因为我的 ajax url 返回 500,因为它没有被赋予 csrf 令牌。

使用获取请求是否不太安全?人们可以欺骗来自外部站点的请求吗?我只是在寻找没有任何安全漏洞的最佳方法。

这是我的 ajax 代码:

saveHousekeepingNotes();

function saveHousekeepingNotes() {
    $.ajax({
        url: "/ajax/save-notes",
        type: "POST",
        data: 'Here we have some data.',
        beforeSend: function(xhr) {
            $('.notes-status-holder').html('Saving...');
        },
        success: function(data) {
            var jqObj = jQuery(data);
            var d = new Date();
            $('.notes-status-holder').html('autosaved ' + d.toLocaleTimeString());

            setInterval(function() {
                saveHousekeepingNotes();
            }, 5 * 1000);
        },
    });
}

在我的刀片文件中:

<script>$.ajaxSetup({ headers: { 'csrftoken' : '{{ csrf_token() }}' } });</script>

在我的路线中:

Route::group(['middleware' => 'ajax', 'prefix' => 'ajax'], function() {
            Route::any('/save-notes', 'AjaxController@saveNotes');
        });

在我的 ajax 控制器中:

<?php

namespace App\Http\Controllers\Admin\Admin;

use Illuminate\Http\Request;
use Cache;
use Auth;
use App\Database\Website\User\Roleplay;

class AjaxController
{
    public function saveNotes()
    {
        if (!Auth::guest()) {
            $roleplay = Roleplay::where('user_id', Auth::user()->id)->first();
            $roleplay->housekeeping_notes = 'We saved it:) ' . rand(10,40);
            $roleplay->save();
        }
    }
}

我的 ajax 中间件只是检查 $request->ajax() 来验证它是一个 ajax 调用。所以我基本上要问的是如何安全地传递 csrf 令牌? Laravel 能解决这个问题吗?或者有更好的方法吗..

【问题讨论】:

标签: javascript php jquery ajax laravel


【解决方案1】:

好吧,根据Laravel Docs,您最好将您的 csrf 令牌存储在元标记中,如下所示:

<meta name="csrf-token" content="{{ csrf_token() }}">

然后在您的主 javascript 文件中,在每个请求中包含此标头(请注意您提供的标头名称错误):

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

然后它应该工作:)

【讨论】:

  • 为什么使用这个而不是@Advaith 答案,我看到它在文档中但为什么将它存储在元标记中?
  • 这种方式更干净,更 便携 因为你不必丑陋地混合 jsblade ,同时在 header 中提供 CSRF 是一种laravel 的原生方式,它是大多数语言的标准,使用 X-XSRF-TOKEN 作为 csrf 的标头。样品在spring
【解决方案2】:

就用这个吧。

_token: '{{ csrf_token() }}'

这是因为ajax请求也发送了字段名。
通常,如果您创建一个csrf_field,您可以使用名称_token 找到它,只需在此处使用它。

$.ajax({
    url: "/ajax/save-notes",
    type: "POST",
    data: {
        _token: '{{ csrf_token() }}',
        // rest data here
    },
    beforeSend: function(xhr) {
        $('.notes-status-holder').html('Saving...');
    },
    success: function(data) {
        var jqObj = jQuery(data);
        var d = new Date();
        $('.notes-status-holder').html('autosaved ' + d.toLocaleTimeString());

        setInterval(function() {
            saveHousekeepingNotes();
        }, 5 * 1000);
    },
});

【讨论】:

    【解决方案3】:

    如果您想以当前方式传递 csrf,您必须告诉 htaccess 将此标头传递给您的脚本并修改其名称

    <IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    
    RewriteEngine On
    
    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    
    
    # Handle custom csrf Header
        RewriteCond %{HTTP:csrftoken} .
        RewriteRule .* - [E=X-XSRF-TOKEN:%{HTTP:csrftoken}]
    </IfModule>
    

    记住@Afik​​Deri 解决方案更便携。更清洁

    【讨论】:

      猜你喜欢
      • 2015-09-21
      • 2020-12-07
      • 1970-01-01
      • 2015-03-30
      • 2020-01-11
      • 2015-07-17
      • 1970-01-01
      • 2020-07-14
      • 2020-04-05
      相关资源
      最近更新 更多