前不久用 rails 作一个 iOS 应用的后端,因为传递的是 json 得用到 token,在处理用户验证上花了些时间找资料,因为 devise 在某次更新中把 token 认证模块去掉了。 花了点小时整理了下为 devise 添加 token 认证的方法,不过怕使用的方法在某些方面存在一点问题或者是不够成熟,还请各位帮我看看,有问题能指点下。在更改完后我再将文章弄过来分享给其他需要的人。
目前暂时放在我的博客上 http://www.flincllck.com/use-json-authentication-api-on-rails4/
https://github.com/gonzalo-bulnes/simple_token_authentication or https://github.com/lynndylanhurley/devise_token_auth
前者提供了基本的验证功能,后者原本针对 angularjs 开发,但也可以用在普通的 token 场景,但须自己重写接口
之前搞得:
module Concerns
module TokenAuthenticatable
extend ActiveSupport::Concern
included do
# Generate new authentication token (a.k.a. "single access token").
def reset_authentication_token
self.authentication_token = self.class.authentication_token
end
# Generate new authentication token and save the record.
def reset_authentication_token!
reset_authentication_token
save(validate: false)
end
# Generate authentication token unless already exists.
def ensure_authentication_token
reset_authentication_token if authentication_token.blank?
end
# Generate authentication token unless already exists and save the record.
def ensure_authentication_token!
reset_authentication_token! if authentication_token.blank?
end
# Hook called after token authentication.
def after_token_authentication
end
def expire_auth_token_on_timeout
self.class.expire_auth_token_on_timeout
end
end
module ClassMethods
# Generate a token checking if one does not already exist in the database.
def authentication_token
generate_token("authentication_token")
end
# Generate a token by looping and ensuring does not already exist.
def generate_token(column)
loop do
token = Devise.friendly_token
break token unless User.find_by(column => token)
end
end
end
end
end
对比 token 时,别少了计时攻击的防护措施。:)
最简单的是添加一个 warden strategy (例如叫做 my_token_strategy ), 然后
initializers/devise.rb:
config.warden do |manager|
manager[:default_strategies][:user].unshift :my_token_strategy
end
正常的用 authenticate_user!
就好了
建议内存数据库存token
application_controller.rb
中加一个前置过滤器处理是否带token
以及权限等
覆写session_controller.rb
保存token
到 redis
无法使用session
,这里得注意下。