嗨,我是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>
答案 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