Rails 无法通过 X-CSRF-TOKEN header 验证 CSRF 令牌真实性 ajax
Rails Can't verify CSRF token authenticity ajax with X-CSRF-TOKEN header
我尝试在我的数据库中注册一个 service worker 端点,但是当我发送我的 post 数据并获取应用程序时会引发错误。
我想保留csrf验证。你看错了吗?
var ready;
ready = function(){
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/service-worker.js').then(function(reg) {
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
console.log(sub);
var token = $('meta[name=csrf-token]').attr('content')
console.log(token);
return fetch('/register_endpoint', {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({
endpoint: sub.endpoint,
authenticity_token: token
})
});
});
}).catch(function(err) {
console.log('Erreur -> ', err);
});
}
};
$(document).ready(ready);
$(document).on('page:load',ready);
谢谢
这对我也不起作用,所以我重写了这个 verified_request? 方法 CsrfToken
class ApplicationController < ActionController::Base
protect_from_forgery
skip_before_action :verify_authenticity_token, if: :verified_request?
protected
def verified_request?
return true if request.get?
if respond_to?(:valid_authenticity_token?, true)
super || valid_authenticity_token?(session, URI.unescape(request.headers['X-CSRF-TOKEN'] || "") )
else
super || form_authenticity_token == URI.unescape(request.headers['X-CSRF-TOKEN'] || "")
end
end
end
$ajax
或 fetch
两者都适用于您的情况。
let token = function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))};
$.ajax({ url: URL,
type: 'POST',
beforeSend: token,
data: 'someData=' + someData,
success: function(response) {
$('#someDiv').html(response);
}
});
或者:
return fetch( URL, {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({endpoint: sub.endpoint}),
credentials: 'same-origin'
})
问题是,如果 credentials
未指定为 fetch
中的选项,则不会发送会话 cookie。
credentials
有 3 possible values:
omit
-> 不发送 cookie
same-origin
-> 仅当 URL 与调用脚本 同源时才发送 cookie
include
-> 始终发送 cookie,即使是跨源调用
所以这应该可行:
return fetch('/register_endpoint', {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({endpoint: sub.endpoint}),
credentials: 'same-origin'
})
Here 有关本机提取的更多信息 api。
我尝试在我的数据库中注册一个 service worker 端点,但是当我发送我的 post 数据并获取应用程序时会引发错误。
我想保留csrf验证。你看错了吗?
var ready;
ready = function(){
if ('serviceWorker' in navigator) {
console.log('Service Worker is supported');
navigator.serviceWorker.register('/service-worker.js').then(function(reg) {
reg.pushManager.subscribe({
userVisibleOnly: true
}).then(function(sub) {
console.log('endpoint:', sub.endpoint);
console.log(sub);
var token = $('meta[name=csrf-token]').attr('content')
console.log(token);
return fetch('/register_endpoint', {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({
endpoint: sub.endpoint,
authenticity_token: token
})
});
});
}).catch(function(err) {
console.log('Erreur -> ', err);
});
}
};
$(document).ready(ready);
$(document).on('page:load',ready);
谢谢
这对我也不起作用,所以我重写了这个 verified_request? 方法 CsrfToken
class ApplicationController < ActionController::Base
protect_from_forgery
skip_before_action :verify_authenticity_token, if: :verified_request?
protected
def verified_request?
return true if request.get?
if respond_to?(:valid_authenticity_token?, true)
super || valid_authenticity_token?(session, URI.unescape(request.headers['X-CSRF-TOKEN'] || "") )
else
super || form_authenticity_token == URI.unescape(request.headers['X-CSRF-TOKEN'] || "")
end
end
end
$ajax
或 fetch
两者都适用于您的情况。
let token = function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))};
$.ajax({ url: URL,
type: 'POST',
beforeSend: token,
data: 'someData=' + someData,
success: function(response) {
$('#someDiv').html(response);
}
});
或者:
return fetch( URL, {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({endpoint: sub.endpoint}),
credentials: 'same-origin'
})
问题是,如果 credentials
未指定为 fetch
中的选项,则不会发送会话 cookie。
credentials
有 3 possible values:
omit
-> 不发送 cookiesame-origin
-> 仅当 URL 与调用脚本 同源时才发送 cookie
include
-> 始终发送 cookie,即使是跨源调用
所以这应该可行:
return fetch('/register_endpoint', {
method: 'post',
headers: {
'Content-type': 'application/json',
'X-CSRF-TOKEN': token
},
body: JSON.stringify({endpoint: sub.endpoint}),
credentials: 'same-origin'
})
Here 有关本机提取的更多信息 api。