我正在前端使用Ember开发无头Rails应用程序。我一直在尝试使用设计进行身份验证。
我遵循了本教程:Started POST "/users/sign_in" for 127.0.0.1 at 2018-05-12 01:36:58 -0700
Processing by SessionsController#create as JSON
Parameters: {"user"=>{"password"=>"[FILTERED]"}, "session"=>{"user"=>{"password"=>"[FILTERED]"}}}
HTTP Origin header (http://localhost:4200) didn't match request.base_url (http://localhost:3000)
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)
ActionController::InvalidAuthenticityToken
(ActionController::InvalidAuthenticityToken):
但我在日志中得到以下内容:
:3000
我在默认端口:4200
本地运行我的rails应用程序,并在默认端口ember-cli-cors
本地运行ember实例(在不同目录之外)。
我已经安装了ember install ember-cli-content-security-policy
和//config/environment.js
module.exports = function(environment) {
let ENV = {
modulePrefix: 'dino-ui',
environment,
rootURL: '/',
locationType: 'auto',
contentSecurityPolicy: {
'default-src': "'self' *",
'script-src': "'self' *",
'connect-src': "'self' *"
},
EmberENV: {
FEATURES: {
},
EXTEND_PROTOTYPES: {
Date: false
}
},
APP: {
}
};
ENV['ember-simple-auth'] = {
routeAfterAuthentication: 'dashboard',
routeIfAlreadyAuthenticated: 'dashboard'
}
...
return ENV;
}
//components/login-form.js
import Ember from 'ember';
const { service } = Ember.inject;
export default Ember.Component.extend({
session: service('session'),
actions: {
authenticate: function() {
let { email, password } = this.getProperties('email', 'password');
return this.get('session').authenticate('authenticator:devise', email, password).catch((reason) => {
this.set('errorMessage', reason.error);
});
}
}
});
//templates/login-form.hbs
<form {{action "authenticate" on="submit"}}>
<label for="email">Login</label>
{{input value=email placeholder="Enter Login"}}
<label for="password">Password</label>
{{input value=password type="password" placeholder="Enter Password"}}
<button type="submit">Login</button>
</form>
{{#if errorMessage}}
{{errorMessage}}
{{/if}}
//application.rb
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :put, :delete, :options, :patch, :head]
end
end
config.middleware.use ActionDispatch::Flash
....
//controllers/application.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception, prepend: true
before_action :authenticate_user_from_token!
before_action :authenticate_user!
private
def authenticate_user_from_token!
authenticate_with_http_token do |token, options|
user_email = options[:email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
end
//controllers/sessions.rb
class SessionsController < Devise::SessionsController
respond_to :html, :json
def create
super do |user|
if request.format.json?
data = {
token: user.authentication_token,
email: user.email
}
render json: data, status: 201 and return
end
end
end
end
,并尝试了我所知道的一切以使其正常运行。非常感谢任何帮助。
以下是我的文件:
{{1}}
答案 0 :(得分:2)
该错误与Rails中的跨站点请求伪造检查有关。当您运行Rails服务器呈现的应用程序时,它会确认该请求来自Rails正在呈现应用程序的域,而不是恶意第三方。正如您所做的那样禁用protect_from_forgery
是您的正确修复,因为您的意图是来自不同服务器(即端口)的请求。
答案 1 :(得分:1)
有趣 - 似乎在应用程序控制器中注释了protect_from_forgery可以解决问题。 登录现在正在运行,但我不确定为什么要修复它。 结果应用程序控制器:
class ApplicationController < ActionController::Base
before_action :authenticate_user_from_token!
before_action :authenticate_user!
# protect_from_forgery with: :exception, prepend: true
private
def authenticate_user_from_token!
authenticate_with_http_token do |token, options|
user_email = options[:email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
end