如何处理 Grape API 和 token_and_options 中的身份验证令牌字符串?
How to handle authentication token string in Grape API and token_and_options?
我正在使用 Ember
front-end 和 Grape
API 并验证一个页面,我有类似的东西:
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
headers['Authorization']
)
end
目前我正在使用 ember-simple-auth
发送类似于 header:
的内容
Token token="n2Rs5tokenLH", email="my@email.com"
查看葡萄记录器:
User Load (38.1ms) SELECT "users".* FROM "users" WHERE "users"."authentication_token" = 'Token token="n2Rs5tokenLH", email="my@email.com"' LIMIT 1
现在rails我通常使用authenticate_or_request_with_http_token
来处理这个问题。而且我不想使用 gsub
或正则表达式之类的东西手动处理这个问题。在 Grape 中处理这个问题的最佳方法是什么?
请注意,Grape API 安装在 rails 项目和 app/api/backend/v1/default.rb
内:
module Backend
module V1
module Defaults
extend ActiveSupport::Concern
included do
version 'v1', using: :path
format :json
prefix :api
rescue_from :all do |e|
Backend::Base.logger.error e
end
helpers do
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
headers['Authorization']
)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
end
end
end
end
编辑:
我刚刚发现我可以使用 ActionController::HttpAuthentication::Token.token_and_options
来完成这项工作,但是我不确定我应该如何将其包含在 Grape
项目中。
应用程序的结构如下所示:
⇒ tree app/api
app/api
└── backend
├── base.rb
└── v1
├── defaults.rb
└── ....
我试图将 ActionController::HttpAuthentication::Token
包含在 defaults.rb
中,例如:
helpers do
include ActionController::HttpAuthentication::Token
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
token_and_options(headers['Authorization'])
)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
但现在我得到:
undefined method `authorization' for #<String:0x007ff51cdb85f8>
我必须添加一个自定义的 token_and_options
函数,它看起来像:
def token_and_options(auth_string)
if header = auth_string.to_s[/^Token (.*)/]
values = .split(',').
inject({}) do |memo, value|
value.strip!
key, value = value.split(/\=\"?/)
value.chomp!('"')
value.gsub!(/\\"/, '"')
memo.update(key => value)
end
values.delete("token")
end
end
然后用类似的东西解析令牌:token_and_options(headers['Authorization'])
你走在正确的道路上:使用 token_params_from 并直接传递授权 header。
helpers do
include ActionController::HttpAuthentication::Token
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(token)
end
def token
token_params_from(headers['Authorization']).shift[1]
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
undefined method
异常是由于 token_and_options 期望 ActionDispatch::Request object 您提供的字符串。
我正在使用 Ember
front-end 和 Grape
API 并验证一个页面,我有类似的东西:
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
headers['Authorization']
)
end
目前我正在使用 ember-simple-auth
发送类似于 header:
Token token="n2Rs5tokenLH", email="my@email.com"
查看葡萄记录器:
User Load (38.1ms) SELECT "users".* FROM "users" WHERE "users"."authentication_token" = 'Token token="n2Rs5tokenLH", email="my@email.com"' LIMIT 1
现在rails我通常使用authenticate_or_request_with_http_token
来处理这个问题。而且我不想使用 gsub
或正则表达式之类的东西手动处理这个问题。在 Grape 中处理这个问题的最佳方法是什么?
请注意,Grape API 安装在 rails 项目和 app/api/backend/v1/default.rb
内:
module Backend
module V1
module Defaults
extend ActiveSupport::Concern
included do
version 'v1', using: :path
format :json
prefix :api
rescue_from :all do |e|
Backend::Base.logger.error e
end
helpers do
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
headers['Authorization']
)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
end
end
end
end
编辑:
我刚刚发现我可以使用 ActionController::HttpAuthentication::Token.token_and_options
来完成这项工作,但是我不确定我应该如何将其包含在 Grape
项目中。
应用程序的结构如下所示:
⇒ tree app/api
app/api
└── backend
├── base.rb
└── v1
├── defaults.rb
└── ....
我试图将 ActionController::HttpAuthentication::Token
包含在 defaults.rb
中,例如:
helpers do
include ActionController::HttpAuthentication::Token
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(
token_and_options(headers['Authorization'])
)
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
但现在我得到:
undefined method `authorization' for #<String:0x007ff51cdb85f8>
我必须添加一个自定义的 token_and_options
函数,它看起来像:
def token_and_options(auth_string)
if header = auth_string.to_s[/^Token (.*)/]
values = .split(',').
inject({}) do |memo, value|
value.strip!
key, value = value.split(/\=\"?/)
value.chomp!('"')
value.gsub!(/\\"/, '"')
memo.update(key => value)
end
values.delete("token")
end
end
然后用类似的东西解析令牌:token_and_options(headers['Authorization'])
你走在正确的道路上:使用 token_params_from 并直接传递授权 header。
helpers do
include ActionController::HttpAuthentication::Token
def current_user
return nil if headers['Authorization'].nil?
@current_user ||= User.find_by_authentication_token(token)
end
def token
token_params_from(headers['Authorization']).shift[1]
end
def authenticate!
error!('401 Unauthorized', 401) unless current_user
end
end
undefined method
异常是由于 token_and_options 期望 ActionDispatch::Request object 您提供的字符串。