这是我的 SessionsController:
class SessionsController < Devise::SessionsController
respond_to :json
def create
resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#failure")
sign_in(resource_name, resource)
return render json: { success: true, path: root_path }
end
def failure
return render json: { success: false, errors: ['Login information is incorrect, please try again'] }
end
end
用户#active_for_authentication
def active_for_authentication?
super && active_flag == 1 && has_active_subscription?
end
服务器响应:
Started POST "/users/sign_in" for 127.0.0.1 at 2013-07-29 15:11:39 -0500
Processing by SessionsController#create as JSON
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ozQ00tw9rRWExCmlIyIZR07ovnTLab5w0W44cLAKwA4=", "user"=>{"email"=>"<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2440414a4a4d570f40484f574e42404f424e57406456414756514d505045484f0a474b49" rel="noreferrer noopener nofollow">[email protected]</a>", "password"=>"[FILTERED]"}, "commit"=>"Sign In"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."type" IN ('User', 'Athlete', 'Coach') AND "users"."email" = '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0165646f6f68722a656d6a726b67656a676b7265417364627374687575606d6a2f626e6c" rel="noreferrer noopener nofollow">[email protected]</a>' LIMIT 1
(0.6ms) BEGIN
AccountType Load (0.5ms) SELECT "account_types".* FROM "account_types" WHERE "account_types"."id" = $1 LIMIT 1 [["id", 3]]
AccountType Load (0.7ms) SELECT "account_types".* FROM "account_types" WHERE "account_types"."id" = 3 LIMIT 1
(0.5ms) COMMIT
Completed 401 Unauthorized in 338ms
Started GET "/users/sign_in.json" for 127.0.0.1 at 2013-07-29 15:11:40 -0500
Processing by SessionsController#new as JSON
Completed 200 OK in 13ms (Views: 1.6ms | ActiveRecord: 0.0ms)
由于某种原因,浏览器中的请求包含一个以电子邮件和密码作为属性的用户对象。无论出于何种原因,失败 json 都不会呈现。不知道我做错了什么
编辑
#Devise
config.http_authenticatable_on_xhr = false
CoffeeScript :
$(document).on 'ajax:success', '.user_modal_form', (e, data) ->
context = $(this)
if data.success
$('input[type="submit"]', context).hide()
$('.spinner', context).show()
if data.path?
window.location.href = data.path
else
location.reload()
else
e.preventDefault()
if data.errors?
$('.error-messages', context).html(data.errors).parent().show()
else
$('button', context).show()
$('.spinner', context).hide()
$('.alert', context).show()
false
最佳答案
这就是我最终为那些以后可能会偶然发现这一点的人所做的事情......
#config/initializers/devise.rb:
config.http_authenticatable_on_xhr = true
config.navigational_formats = [:"*/*", "*/*", :html, :json]
session Controller
class SessionsController < Devise::SessionsController
respond_to :json
def create
resource = warden.authenticate!(scope: resource_name, recall: "#{controller_path}#failure")
sign_in(resource_name, resource)
return render json: { success: true, path: root_path }
end
def failure
return render json: { success: false, errors: ['Login information is incorrect, please try again'] }
end
end
路线
# I have implemented STI (Single Table Inheritance) into my app, therefore I skip sessions and passwords for the :user scope
devise_for :users, skip: :registrations, controllers: { sessions: "sessions", passwords: "passwords" }
用户模型
def active_for_authentication?
super && active_flag == 1 && has_active_subscription?
end
def inactive_message
"Your subscription has been canceled or has expired."
end
CoffeeScript :
$(document).on 'ajax:success', '.user_modal_form', (e, data) ->
context = $(this)
log data
if data.success
$('input[type="submit"]', context).hide()
$('.spinner', context).show()
if data.path?
window.location.href = data.path
else
location.reload()
else
e.preventDefault()
if data.errors?
$('.error-messages', context).html(data.errors).parent().show()
else
$('button', context).show()
$('.spinner', context).hide()
$('.alert', context).show()
false
.on 'ajax:error', '.user_modal_form', (event, xhr, ajaxOptions, thrownError) ->
json = $.parseJSON(xhr.responseText)
$('.error-messages', $(this)).html(json.error).parent().show()
关于ruby-on-rails - 设计在身份验证失败时使用 JSON 请求登录不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17933117/