Laravel TokenMismatchException в ajax-запросе
Я использую группу ресурсов и использую этот фильтр для решения проблемы TokenMismatchException
:
Route::filter('csrf', function($route, $request) {
if (strtoupper($request -> getMethod()) === 'GET') {
return;
// get requests are not CSRF protected
}
$token = $request -> ajax() ? $request -> header('X-CSRF-Token') : Input::get('_token');
if (Session::token() != $token) {
throw new Illuminate\Session\TokenMismatchException;
}
});
мой маршрут:
Route::group(array('prefix'=> 'admin', 'before' => 'csrf'), function(){
Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
});
в настоящее время. Я получаю ошибку для запросов Ajax, таких как этот код:
<script type="text/javascript">
$(document).ready(function() {
$('#frm').submit(function(e){
e.preventDefault();
name = $('#name').val();
family = $('#family').val();
email = $('#email').val();
currPassword = $('#currPassword').val();
password = $('#password').val();
password_confirmation = $('#password_confirmation').val();
$.post("{{ route('admin.profile.update', $profile->id) }}",
{
_method : 'PUT',
name : name,
family : family,
email : email,
currPassword : currPassword,
password : password,
password_confirmation : password_confirmation
},
function(data)
{
alert(data.errors.name);
},'json');
return false;
});
});
</script>
ERROR:
{"error":{"type":"Illuminate\\Session\\TokenMismatchException","message":"","file":"\/var\/www\/alachiq\/app\/filters.php","line":83}}
Я думаю, что я должен быть отправлен _token в $.post
. но я не могу получить тег input
с атрибутом name
. iget эту ошибку:
TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement.
Ответы
Ответ 1
В документах Laravel есть подсказка о том, как это сделать. Возможно, это не было доступно во время вопроса, но я подумал, что обновляю его с ответом.
http://laravel.com/docs/master/routing#csrf-x-csrf-token
Я проверил метод метатега из документации и получил его работу. Добавьте в свой глобальный шаблон следующий метатег
<meta name="csrf-token" content="{{ csrf_token() }}">
Добавьте этот JavaScript, который устанавливает значения по умолчанию для всех запросов ajax в jQuery. Предпочтительно в файле js, который включен в ваше приложение.
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
})
Этот токен может существовать в заголовке запроса или форме. Это заполняет его в заголовке запроса для каждого запроса ajax.
Ответ 2
Вам нужно вставить скрытый ввод с помощью _token, а затем получить это значение, как вы делаете, чтобы получить другие поля формы в своем сообщении ajax.
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
Другой метод
В вашем представлении вы можете установить объект с помощью _token
<script type="text/javascript">
var _globalObj = {{ json_encode(array('_token'=> csrf_token())) }}
</script>
а затем при вызове ajax вы можете получить _token от объекта следующим образом:
var token = _globalObj._token;
и включить его в сообщение ajax.
Ответ 3
Просто выполните простую вещь, как я показал в следующем коде,
$.ajax({
type: 'POST',
url: 'your-post-route-url',
data: {
"_token": "{{ csrf_token() }}",
"form_data": $('#Form').serialize(),
},
success: function (data) {
console.log(data);
},
error: function (reject) {
console.log(reject);
}
});
Надеюсь, это самый простой способ решить эту проблему без какого-либо скрытого поля, и это работает для меня в версии laravel 5.4:)
Надеюсь, что это поможет.
Ответ 4
Вы также можете добавить URL-адрес, который дает вам ошибку внутри файла VerifyCsrfToken.php
в
protected $except = [
//
]
Скажем, ваш маршрут - сообщение. Вы можете просто добавить это
protected $except = ['post',
//
];`...
Надеюсь, что это поможет другим.
Ответ 5
<html>
<head>
<title>Ajax Example</title>
<meta name="csrf-token" content="<?php echo csrf_token() ?>" />
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
</script>
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
<script>
function getMessage(){
$.ajax({
type:'POST',
url:'/getmsg',
data:'_token = <?php echo csrf_token() ?>',
data:'',
success:function(data){
$("#msg").html(data.msg);
}
});
}
</script>
</head>
<body>
<div id = 'msg'>This message will be replaced using Ajax.
Click the button to replace the message.</div>
<?php
echo Form::button('Replace Message',['onClick'=>'getMessage()']);
?>
</br>
</body>
</html>
и VerifyCsrfToken.php
добавить эту функцию
protected function tokensMatch($request)
{
// If request is an ajax request, then check to see if token matches token provider in
// the header. This way, we can use CSRF protection in ajax requests also.
$token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');
return $request->session()->token() == $token;
}