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.
我的问题很简单:有没有一种好方法可以使用 Rails 4 对来自原生 Android 和 iPhone 应用程序的用户进行身份验证?有谁知道提供解决方案的好教程或文章?
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?!:
假设我们有一个 User
记录.用户注册了一个帐户,该帐户在数据库中创建了一个 User
记录,其中包含一个 email
列和一个 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?
有管理这些的宝石吗?
抱歉,这里完全不确定.
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 railscast 中的 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
用户模型.
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[控制器和模型] https://github.com/danahartweg/authenticable_rest_api
The code is from: [SHA1 HMAC Key generation/authentication] https://github.com/mgomes/api_auth [Controllers & Models] https://github.com/danahartweg/authenticatable_rest_api
这篇关于Rails api 和本机移动应用程序身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!