Rails,Devise 无法使用 cURL 退出。
Rails, Devise can not use cURL to signout.
我正在关注 this tutorial to create user authentication with devise from Android. However, Devise remove :token_authenticable
hence, I am using what they refer in this gist。但是,我 运行 遇到了一些我不知道如何解决的问题。
这是代码。
在用户模型中。
before_save :ensure_authentication_token
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
def skip_confirmation!
self.confirmed_at = Time.now
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless User.where(authentication_token: token).first
end
end
在应用程序控制器中:
protect_from_forgery with: :exception
before_filter :authenticate_user_from_token!
private
# For this example, we are simply using token authentication
# via parameters. However, anyone could use Rails's token
# authentication features to get the token from a header.
def authenticate_user_from_token!
user_token = params[:user_token].presence
user = user_token && User.find_by_authentication_token(user_token.to_s)
if user
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
end
end
在会话控制器中API
class Api::SessionsController < Devise::SessionsController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
before_action :authenticate_user_from_token!, only: [:create]
respond_to :json
def create
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_in"),
:data => { :auth_token => current_user.authentication_token } }
end
def destroy
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
current_user.update_column(:authentication_token, nil)
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_out"),
:data => {} }
end
结束
当我执行curl登录时:
curl -v -H 'Content-Type: appl-H 'Accept: application/json' -X POST http://localhost:3000/api/sessions -d "{\"user\":{\"email\":\"[FILTERED]\",\"password\":\"123123123\"}}"
这是来自服务器的日志:
Started POST "/api/sessions" for 127.0.0.1 at 2015-01-23 13:47:05 +1300
Processing by Api::SessionsController#create as JSON
Parameters: {"user"=>{"email"=>"[FILTERED]", "password"=>"[FILTERED]"}, "session"=>{"user"=>{"email"=>"[FILTERED]", "password"=>"[FILTERED]"}}}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = '[FILTERED]' ORDER BY "users"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (0.2ms) UPDATE "users" SET "current_sign_in_at" = ?, "last_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = 1 [["current_sign_in_at", "2015-01-23 00:47:05.981119"], ["last_sign_in_at", "2015-01-23 00:28:49.300907"], ["sign_in_count", 3], ["updated_at", "2015-01-23 00:47:05.981736"]]
(103.8ms) commit transaction
Completed 200 OK in 185ms (Views: 0.4ms | ActiveRecord: 104.9ms)
当我执行 curl 以注销时:
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X DELETE http://localhost:3000/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF
这是服务器日志:
Started DELETE "/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF" for 127.0.0.1 at 2015-01-23 13:50:22 +1300
Processing by Api::SessionsController#destroy as JSON
Parameters: {"auth_token"=>"TbQXZJtngfJqZK6HkHKF", "session"=>{}}
Filter chain halted as :verify_signed_out_user rendered or redirected
Completed 204 No Content in 1ms (ActiveRecord: 0.0ms)
当我在 SessionController API 中添加 skip_filter:verify_signed_out_user, only:[:destroy]
时,服务器日志将是:
Started DELETE "/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF" for 127.0.0.1 at 2015-01-23 13:58:55 +1300
Processing by Api::SessionsController#destroy as JSON
Parameters: {"auth_token"=>"TbQXZJtngfJqZK6HkHKF", "session"=>{}}
Completed 401 Unauthorized in 1ms
我不明白为什么 returns 204 没有内容....
如果有人知道发生了什么。我们将不胜感激。
干杯。
成功销毁资源的 HTTP 状态为 204。查看 http://httpstatus.es/204 了解更多信息。
当您跳过过滤器时,它会返回 401,即未授权访问资源的 HTTP 状态。这是正确的,因为您在销毁结果之前要求进行身份验证。
一切似乎都是正确的,我看不出问题。
我正在关注 this tutorial to create user authentication with devise from Android. However, Devise remove :token_authenticable
hence, I am using what they refer in this gist。但是,我 运行 遇到了一些我不知道如何解决的问题。
这是代码。
在用户模型中。
before_save :ensure_authentication_token
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable
def ensure_authentication_token
if authentication_token.blank?
self.authentication_token = generate_authentication_token
end
end
def skip_confirmation!
self.confirmed_at = Time.now
end
private
def generate_authentication_token
loop do
token = Devise.friendly_token
break token unless User.where(authentication_token: token).first
end
end
在应用程序控制器中:
protect_from_forgery with: :exception
before_filter :authenticate_user_from_token!
private
# For this example, we are simply using token authentication
# via parameters. However, anyone could use Rails's token
# authentication features to get the token from a header.
def authenticate_user_from_token!
user_token = params[:user_token].presence
user = user_token && User.find_by_authentication_token(user_token.to_s)
if user
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
end
end
在会话控制器中API
class Api::SessionsController < Devise::SessionsController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
before_action :authenticate_user_from_token!, only: [:create]
respond_to :json
def create
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_in"),
:data => { :auth_token => current_user.authentication_token } }
end
def destroy
warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#failure")
current_user.update_column(:authentication_token, nil)
render :status => 200,
:json => { :success => true,
:info => t("devise.sessions.signed_out"),
:data => {} }
end
结束
当我执行curl登录时:
curl -v -H 'Content-Type: appl-H 'Accept: application/json' -X POST http://localhost:3000/api/sessions -d "{\"user\":{\"email\":\"[FILTERED]\",\"password\":\"123123123\"}}"
这是来自服务器的日志:
Started POST "/api/sessions" for 127.0.0.1 at 2015-01-23 13:47:05 +1300
Processing by Api::SessionsController#create as JSON
Parameters: {"user"=>{"email"=>"[FILTERED]", "password"=>"[FILTERED]"}, "session"=>{"user"=>{"email"=>"[FILTERED]", "password"=>"[FILTERED]"}}}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = '[FILTERED]' ORDER BY "users"."id" ASC LIMIT 1
(0.1ms) begin transaction
SQL (0.2ms) UPDATE "users" SET "current_sign_in_at" = ?, "last_sign_in_at" = ?, "sign_in_count" = ?, "updated_at" = ? WHERE "users"."id" = 1 [["current_sign_in_at", "2015-01-23 00:47:05.981119"], ["last_sign_in_at", "2015-01-23 00:28:49.300907"], ["sign_in_count", 3], ["updated_at", "2015-01-23 00:47:05.981736"]]
(103.8ms) commit transaction
Completed 200 OK in 185ms (Views: 0.4ms | ActiveRecord: 104.9ms)
当我执行 curl 以注销时:
curl -v -H 'Content-Type: application/json' -H 'Accept: application/json' -X DELETE http://localhost:3000/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF
这是服务器日志:
Started DELETE "/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF" for 127.0.0.1 at 2015-01-23 13:50:22 +1300
Processing by Api::SessionsController#destroy as JSON
Parameters: {"auth_token"=>"TbQXZJtngfJqZK6HkHKF", "session"=>{}}
Filter chain halted as :verify_signed_out_user rendered or redirected
Completed 204 No Content in 1ms (ActiveRecord: 0.0ms)
当我在 SessionController API 中添加 skip_filter:verify_signed_out_user, only:[:destroy]
时,服务器日志将是:
Started DELETE "/api/sessions/?auth_token=TbQXZJtngfJqZK6HkHKF" for 127.0.0.1 at 2015-01-23 13:58:55 +1300
Processing by Api::SessionsController#destroy as JSON
Parameters: {"auth_token"=>"TbQXZJtngfJqZK6HkHKF", "session"=>{}}
Completed 401 Unauthorized in 1ms
我不明白为什么 returns 204 没有内容.... 如果有人知道发生了什么。我们将不胜感激。 干杯。
成功销毁资源的 HTTP 状态为 204。查看 http://httpstatus.es/204 了解更多信息。
当您跳过过滤器时,它会返回 401,即未授权访问资源的 HTTP 状态。这是正确的,因为您在销毁结果之前要求进行身份验证。
一切似乎都是正确的,我看不出问题。