Laravel 5.7 Ajax发布请求返回419状态码

时间:2018-12-18 03:06:56

标签: ajax laravel request token csrf

嗨,我是Laravel的新手,我正在尝试使用ajax表单提交来构建登录表单。

我使用Metronic模板复制并构建了一个示例表单,并尝试使用ajax请求来获取登录检查。

如果将我的代码从VerifyCsrfToken检查中排除,我的代码将完全正常。但是我确实希望令牌验证能够正常工作。

我已阅读多篇有关csrf令牌的文章,尝试过但仍返回状态码419。

很抱歉下面的长代码,但是在这里 (我知道我对设置会话和内容还没有做任何事情,请暂时忽略,因为代码无论如何都返回419状态)

routes / web.php

Route::post('/auth/login', array('uses' => 'Auth\LoginController@postLogin'))->name('login');
Route::get('/landing', array('uses' => 'IndexController@landing'))->name('landing');

login.blade.php

<head>
    <meta charset="utf-8" />
    <title>{{ config('app.name') }} ({{ config('app.env') }})</title>
    <meta name="description" content="Latest updates and statistic charts">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- 
    Global css & js here
    -->
</head>
<body>
    <form class="m-login__form m-form" method="post" action="{{ route('login') }}">
        @csrf
        <!--
        Form content here
        -->
    </form>

    <!--begin::Page Scripts -->
    <script type="text/javascript">
        var form_action = '{{ route('login') }}';
    </script>
    <script src="{{ URL::asset('login.js')}}" type="text/javascript"></script>
    <!--end::Page Scripts -->
</body>

login.js

var handleSignInFormSubmit = function() {
    $('#m_login_signin_submit').click(function(e) {
        e.preventDefault();
        var btn = $(this);
        var form = $(this).closest('form');

        form.validate({
            rules: {
                email: {
                    required: true,
                    email: true
                },
                password: {
                    required: true
                }
            }
        });

        if (!form.valid()) {
            return;
        }

        btn.addClass('m-loader m-loader--right m-loader--light').attr('disabled', true);

        var formData = form.serialize();
        $.ajax({
            url:form_action,
            type:'POST',
            data: formData,
            headers:{
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            dataType: 'json',
            success:function(data){
                if(data.auth){
                    $(location).attr('href', data.intended);
                }
                else{
                    btn.removeClass('m-loader m-loader--right m-loader--light').attr('disabled', false);
                    showErrorMsg(form, 'danger', 'Incorrect username or password. Please try again.');
                }
            },
            error: function (data) {
                btn.removeClass('m-loader m-loader--right m-loader--light').attr('disabled', false);
                showErrorMsg(form, 'danger', 'Incorrect username or password. Please try again.');
            }
        });
    });
}

Auth \ LoginController

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\URL;
use Response;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/landing';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function postLogin(Request $request) {
        $auth = false;
        $credentials = $request->only('email', 'password', 'remember_token');

        if (Auth::attempt($credentials, $request->has('remember_token'))) {
            $auth = true; // Success
        }

        if($auth){
            if ($request->ajax()){
                $response = array(
                    'auth' => true,
                    'code' => 101,
                    'intended' => URL::route('landing')
                );
            }
            else{
                $response = array(
                    'auth' => true,
                    'code' => 102,
                    'intended' => URL::route('landing')
                );
            }
            return Response::json($response);
        }
        else{
            $response = array(
                'status' => 'error',
                'msg' => 'Error',
            );
            return Response::json($response);
        }
    }
}

部分响应错误

message: "", exception: "Symfony\Component\HttpKernel\Exception\HttpException",…}
exception: "Symfony\Component\HttpKernel\Exception\HttpException"
file: "/var/www/imas/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php"
line: 204
message: ""

更新: 我将所有内容都放在一个php文件中,确实将csrf令牌meta放在了head + ajaxsetup的脚本中,仍然得到419状态代码 (注意:“ test123”是路由文件中的发布方法)

<!DOCTYPE html>
<html lang="en">

    <!-- begin::Head -->
    <head>
        <meta charset="utf-8" />
        <title>{{ config('app.name') }} ({{ config('app.env') }})</title>
        <meta name="description" content="Latest updates and statistic charts">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no">
        <meta name="csrf-token" content="{{ csrf_token() }}">


        <!--begin::Web font -->
        <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.16/webfont.js"></script>
        <script>
            WebFont.load({
            google: {"families":["Poppins:300,400,500,600,700","Roboto:300,400,500,600,700"]},
            active: function() {
                sessionStorage.fonts = true;
            }
          });
        </script>

        <!--end::Web font -->

        <!--begin:: Global Mandatory Vendors -->    
        <!--end:: Global Mandatory Vendors -->

        <!--begin:: Global Optional Vendors -->
        <!--end:: Global Optional Vendors -->

        <!--begin::Global Theme Styles -->
        <!--end::Global Theme Styles -->

        <!--begin::Page Vendors Styles -->
        <!--end::Page Vendors Styles -->

        <!--begin:: Custom CSS -->
        @yield('pagespecificstyles')
        <!--end:: Custom CSS -->
    </head>
    <!-- end::Head -->

    <!-- begin::Body -->
    <body class="m-page--fluid m--skin- m-content--skin-light2 m-header--fixed m-header--fixed-mobile m-aside-left--enabled m-aside-left--skin-light m-aside-left--fixed m-aside-left--offcanvas m-footer--push m-aside--offcanvas-default">

        <!-- begin:: Page -->
        <div class="m-grid m-grid--hor m-grid--root m-page">

            <!-- BEGIN: Header -->
            @include('admin.top')
            <!-- END: Header -->

            <!-- begin::Body -->
            <div class="m-grid__item m-grid__item--fluid m-grid m-grid--ver-desktop m-grid--desktop m-body">

                <!-- BEGIN: Left Aside -->
                @include('admin.sidenav')
                <!-- END: Left Aside -->

                <div class="m-grid__item m-grid__item--fluid m-wrapper">
                    <form name="form1" id="form1">
                    Name: <input type="name" name="username" id="username"/><br/>
                    Password: <input type="password" name="password" id="password"/><br/>
                    <input type="button" value="Submit" name="btn_submit" id="btn_submit"/>
                    </form>             
                </div>
            </div>

            <!-- end:: Body -->

            <!-- begin::Footer -->
            @include('admin.footer')
            <!-- end::Footer -->
        </div>

        <!-- end:: Page -->

        <!-- begin::Scroll Top -->      
        @include('admin.scrolltop')
        <!-- end::Scroll Top -->

        <!-- begin:: Script -->
        @include('admin.script')
        @yield('pagespecificscripts')
        <script>
        var formPath = '{{ route('test123') }}';
        $(document).ready(function(){
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $('#btn_submit').click(function(){

            var formData = $('#form1').serialize();
                $.ajax({
                    type:'POST',
                    url:formPath,
                    data:formData,
                    success:function(data){
                        alert(data);
                    }
                });
            });
        });
        </script>
        <!-- end:: Script -->
    </body>

    <!-- end::Body -->
</html>

1 个答案:

答案 0 :(得分:3)

在HTML的开头部分中使用它:

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

然后在您的ajax中将其用于数据:

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

请参阅Laravel文档CSRF Protection