2014-02-05 53 views
29

我知道有很多关于此主题的信息,但是我找不到任何最新的信息。 我看到像this one relating to rails and android authentication这样的话题,但我看到那TokenAuthenticatable is now removed from deviseRails api和原生移动应用程序认证

我的问题很简单:是否有认证,从原生的Android和iPhone用户的好方法使用Rails应用程序4?有谁知道提供解决方案的好教程或文章?

亚当韦特加入悬赏:

我刚刚开了在这个问题上500奖金,因为我无法找到从iOS应用用户随时随地认证到Rails的API的正确做法。这是我正在考虑的事情,但不知道它是否安全?!:

我们假设我们有一个User记录。用户已注册一个帐户,该帐户在数据库中创建了一个User记录,其中email列和password_digest列。

当用户登录,在我想该用户仍然在移动应用中验证,直到明确签约出。

我想我们将需要一个基于令牌的认证。当创建User时,我可能会创建ApiKey记录,并将其保存为User记录中的关联。

当用户登录/注册时,响应将包含一个API令牌(类似于SecureRandom.hex),该令牌将被保存在iOS密钥链中,并与所有后续请求一起用于验证用户,方法是将用户传入头并验证它使用类似的东西:

before_filter :restrict_access 

private 

def restrict_access 
authenticate_or_request_with_http_token do |token, options| 
    ApiKey.exists?(access_token: token) 
end 

这种事情安全吗?我是否应该用每个请求刷新令牌并将其包含在响应中?

我还有其他选择吗? Facebook,Twitter和Pinterest喜欢做什么?

我知道OAuth2.0,但这不是用于授予外部应用程序吗?

是否有宝石管理这些?

对不起,在这里完全不确定。

500以最佳答案。

+1

我已经Finnaly成功我的追求,我现在有一个Rails后端,和Android应用程序能够注册,登录和注销,并且无需每次都重新进行身份验证。我会很快做出例子。它工作得很好,但我不知道它是否安全,我不擅长这一点...所以我等待回应。 –

+0

我可以在iOS上做同样的事情,但是像你一样,不知道它是否会很容易被破解! –

+1

也许[我对这个问题的回答](http://stackoverflow.com/questions/18605294/is-devises-token-authenticatable-secure/18695244#18695244)会有帮助。 – Ashitaka

回答

13

从我的研究的解决方案的要点。随意编辑,修正,无效等。

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算法进行签名。

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密钥的生成。

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算法来签署请求。

的代码是: [SHA1 HMAC密钥生成/认证] https://github.com/mgomes/api_auth [控制器&模型] https://github.com/danahartweg/authenticatable_rest_api

+0

这看起来很有希望!我明天会奖励积分 –

7

你是在正确的轨道上,但是用户的令牌只能用来识别用户发出请求。您仍然需要某种身份验证,因为当您推测每次请求更改令牌时,黑客可能会拦截数据流,获取令牌,然后在随后的请求中“成为”该用户。

通过改变对每个请求令牌,可以消除拦截的问题,但一旦有人截获令牌,他们就可以通过继续拦截它,甚至修改响应利用系统。对此的一个解决方案是使用HMAC(Amazon Web Services使用该HMAC)。它是一种为您的请求提供签名(哈希)的算法,该签名对于每个请求都是唯一的,不需要更改密钥,并且不能为将来的请求预测。

有一个rails的ruby gem,它在服务器端实现HMAC来签署HMAC请求,并在进行服务器到服务器通信时生成它们。对于客户端到服务器的请求,您需要在iOS或Android端生成签名并在服务器上对其进行身份验证。

考虑一下ApiAuth gem来完成服务器端的工作。在iOS客户端,请考虑使用HBHMAC库来生成签名。查看ApiAuth的具体实现,因为它为数据添加了时间戳以防止重放攻击,所以您可能需要在将数据传递给HBHMAC之前向数据添加一个字段。

总之,使用HMAC身份验证将通过利用单向哈希算法来避免中间人攻击和重放攻击,该算法可以防止攻击者即使能够拦截有效请求也能生成可靠请求。

+0

看起来不错,谢谢你的答案。请等待,看看还有什么来通过之前,谢谢 –

5

我有这个问题,我是一个API开发人员。你可能使用令牌和自定义授权困难的方式,但我会告诉你我们的应用程序,我们的应用程序,它为六位数字的用户服务。

至少为iOS,设备会为你处理会话,这意味着如果在iOS应用程序用户发出POST请求/users/sign_in与参数

user: { 
    password: 'mypassword', 
    email: '[email protected]', 
    remember_me: true # optional 
} 

iOS设备将存储会话你,安全地坚持不懈。现在,如果你想要使用OAuth 2路由,我实际上为rails 4提供了一个叫做OAuth 2的gem,我向其中添加了一个非常酷的功能,允许你让用户通过“授权”屏幕,因为很明显,如果您开发了该软件,则不需要用户确认他们信任您。

如果您决定使用OAuth 2,则需要使用所谓的隐式访问令牌。 This is the long and very boring OAuth2 spec for that

钢轨4项目可以在github上 https://github.com/bwheeler96/devise-oauth2-provider-rails4

如果你不上轨道4可以发现,你可以使用原来的宝石 https://github.com/socialcast/devise_oauth2_providable

顺便说,创业板需要工作所以如果有人读这个谁想要帮助改善它,请务必叉this repository

相关问题