Dia*_*ism 6 cookies ajax ruby-on-rails jwt reactjs
很久的潜伏者,第一次在这里发布海报.
有关JWT的许多良好指南和资源以及如何以及在何处存储它们.但是,当涉及到在节点服务器上运行的ReactJS/Flux应用程序和完全独立的Rails API之间安全地存储和发送JWT时,我陷入了僵局.
似乎大多数指南告诉您只需将JWT存储在本地存储中,然后为每个AJAX请求将其解析出来并将其传递到标题中.https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/警告不要这样做,因为本地存储不安全,恶意的人可以访问该令牌.它建议将其存储在cookie中,只是让Web浏览器将其与每个请求一起传递.
这听起来不错,因为根据我的理解,无论如何都可以方便地将cookie与每个请求一起发送.这意味着我可以从我的ReactJS应用程序向我的Rails API发出AJAX请求,并让API将其拔出,检查它,并做到这一点.*
我遇到的问题是我的Node应用程序没有从它从Rails API返回的响应中设置cookie,即使Rails API(在localhost:3000上运行)返回Set-Cookie标头并将其发送回ReactJS/Node应用程序(在localhost:8080上运行).
这是我的Rails API方面的登录控制器操作:
class V1::SessionsController < ApplicationController
def create
user = User.where(email: params[:user][:email]).first!
if user && user.authenticate(params[:user][:password])
token = issue_new_token_for(user)
# I've tried this too.
# cookies[:access_token] = {
# :value => token,
# :expires => 3.days.from_now,
# :domain => 'https://localhost:8080'
# }
response.headers['Set-Cookie'] = "access_token=#{token}"
render json: { user: { id: user.id, email: user.email }, token: token }, status: 200
else
render json: { errors: 'username or password did not match' }, status: 422
end
end
end
Run Code Online (Sandbox Code Playgroud)
它的要点是它需要一个电子邮件和密码,查看用户,并在信息检出时生成JWT.
这是从我的Node应用程序调用它的AJAX请求:
$.ajax({
url: 'http://localhost:3000/v1/login',
method: 'post',
dataType: 'json',
data: {
user: {
email: data.email,
password: data.password
},
callback: '' //required to get around ajax CORS
},
success: function(response){
console.log(response);
},
error: function(response) {
console.log(response);
}
})
Run Code Online (Sandbox Code Playgroud)
检查Rails API的响应显示它有一个Set-Cookie标头,其值为access_token = jwt.token.here
屏幕截图: Chrome Dev Tools Inspector屏幕截图
但是,localhost:8080没有显示任何cookie设置,并且我的Node/React应用程序的后续AJAX调用没有与它们一起发送任何cookie.
我的问题是,我误解了哪些内容.在这种情况下,如何在cookie中存储JWT需要做些什么?
一个后续问题:假设将JWT存储在cookie中不是一种选择,将JWT存储在本地存储中会有什么潜在的安全风险(假设我没有在JWT中放置任何敏感信息,它们都会在一些任意的时间)?
*这可能是我的一个根本误解.如果我有这个错误,请直截了当.
可能感兴趣的附注:
更新 elithrar提交了一个有效的答案:
我需要用xhrFields和crossDomain修改我的AJAX请求,并告诉jQuery支持cors:
$.support.cors = true;
$.ajax({
url: 'http://localhost:3000/v1/login',
method: 'post',
dataType: 'json',
xhrFields: {
withCredentials: true
},
crossDomain: true,
data: {
user: {
email: data.email,
password: data.password
}
},
success: function(response){
console.log(response);
},
error: function(response) {
console.log(response);
}
})
Run Code Online (Sandbox Code Playgroud)
我添加了凭据:true并公开:我的Rails API上的Rack Cors配置是真的(*仅适用于我的开发环境):
config.middleware.insert_before 0, 'Rack::Cors' do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :put, :path, :options], credentials: true, expose: true
end
Run Code Online (Sandbox Code Playgroud)
结束