Rails api和本地移动应用程序身份验证 [英] Rails api and native mobile app authentication
问题描述
我知道有关这个话题的信息很多,但我找不到最新的信息。
我看到主题,如这个一个涉及到rails和android身份验证,但是我看到 TokenAuthenticatable
现在从设计中删除。
I know there is a lot of information about this topic, but I can't find any that is up to date.
I see topics like this one relating to rails and android authentication but I see that TokenAuthenticatable
is now removed from devise.
我的问题很简单:有一个很好的方法来验证来自本机Android和iPhone应用程序的用户使用Rails 4?有没有人知道提供解决方案的好教程或文章?
My question is simple: is there a good way to authenticate users from native Android and iPhone apps using Rails 4? Does anyone know of good tutorials or articles that provide a solution ?
Adam Waite添加赏金:
我刚刚在这个问题上开了500个赏金,因为我无法找到从iOS应用程序向Rails API进行身份验证的正确做法。这是我正在考虑做的,但不知道它是否安全?!:
I have just opened a 500 bounty on this question because I can't find the correct practice for authenticating a user from an iOS app to a Rails API anywhere. This is what I was considering doing but have no idea if it's secure or not?!:
我们假设我们有一个用户
记录。用户已经注册了一个帐户,该帐户在数据库中创建了一个用户
记录,其中包含电子邮件
列和 password_digest
列。
Let's assume we have a User
record. A user has signed up for an account which has created a User
record in the database with an email
column and a password_digest
column.
当用户登录时,我希望该用户在移动应用上保持身份验证,直到明确退出。
When the user signs-in I would like that user to remain authenticated on the mobile app until explicitly signing-out.
我想我们将需要一个基于令牌的身份验证。当$ User
创建时,我可能会创建一个ApiKey记录,并将其保存为 User
记录中的关联。
I imagine we're going to need a token based authentication. I would perhaps create an ApiKey record when the User
is created and have that saved as an association on the User
record.
当用户登录/登录时,响应将包含API令牌(类似于 SecureRandom.hex
)这将保存在iOS钥匙串中,并与所有后续请求一起使用,以通过将其传递给标题并使用以下方式验证用户来验证用户:
When the user signs in/up, the response will contain an API token (something like SecureRandom.hex
) which will be saved in the iOS Keychain and used with all subsequent requests to verify the user by passing it in a header and verifying it using something like:
before_filter :restrict_access
private
def restrict_access
authenticate_or_request_with_http_token do |token, options|
ApiKey.exists?(access_token: token)
end
?我应该在每个请求中刷新令牌,并将其包含在响应中?
Is this secure? Should I be refreshing the token with every request and including it in the response?
我还有什么其他选项? Facebook,Twitter和Pinterest喜欢做什么?
What other options do I have? What do the likes of Facebook, Twitter and Pinterest do?
我知道OAuth2.0,但是不是授予外部应用程序?
I am aware of OAuth2.0, but is that not for granting external applications?
有没有管理这些的宝石?
Is there a gem that manages any of this?
对不起,完全不确定这里。
Sorry, completely unsure here.
500最佳答案。
推荐答案
从我的研究。请自由编辑,更正,无效等。
Gist of a solution from my research. Feel free to edit, correct, invalidate, etc.
SessionsController < ApplicationController
skip_before_filter :authenticate_user, :only => [:create]
def create
user = User.where("username = ? OR email = ?", params[:username_or_email], params[:username_or_email]).first
if user && user.authenticate(params[:password])
api_key = user.find_api_key
if !api_key.secret_key || api_key.is_expired?
api_key.set_expiry_date
api_key.generate_secret_key
end
api_key.save
render json: api_key, status: 201
else
status: 401
end
end
注意ApiAuth.authentic?方法和请求对象。请求必须使用客户端上的HMAC算法进行签名。
Note the ApiAuth.authentic? method and the request object. The request must be signed with an HMAC algorithm on the client.
ApplicationController < ActionController::Base
respond_to :json
force_ssl
protect_from_forgery with: :null_session
before_filter :authenticate_user
private
def authenticate_user
if authenticate_user_from_secret_key
return true
else
head :unauthorized
end
end
def authenticate_user_from_secret_key
userid = ApiAuth.access_id(request)
currentuser = userid && User.find_by_id(userid)
if ApiAuth.authentic?(request, currentuser.find_api_key.secret_key)
return true
else
return false
end
false
end
用户创建/注册
UsersController < ApplicationController
skip_before_filter :authenticate_user, :only => [:create]
def create
user = User.create(user_params)
if !user.new_record?
render json: user.find_apit_key, status: 201
else
# error
end
end
Api键模型。类似于#352 railsscast中的api密钥模型只有区别是ApiAuth密钥生成。
Api key model. Similar to api key model in #352 railscast only difference is ApiAuth key generation.
class ApiKey < ActiveRecord::Base
before_create :generate_secret_key, :set_expiry_date
belongs_to :user
def generate_secret_key
begin
self.secret_key = ApiAuth.generate_secret_key
end while self.class.exists?(secret_key: secret_key)
end
用户模型。 >
User model.
class User < ActiveRecord::Base
has_secure_password
before_save :ensure_api_key
has_many :api_keys
def find_api_key
self.api_keys.active.ios.first_or_create
end
在客户端,HMAC算法必须用于签署请求。
On the client side the HMAC algorithm must be used to sign requests.
代码来自:
[SHA1 HMAC密钥生成/认证] https://github.com/mgomes/ api_auth
[Controllers&模型] https://github.com/danahartweg/authenticatable_rest_api
这篇关于Rails api和本地移动应用程序身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!