Rails api 和本机移动应用程序身份验证 [英] Rails api and native mobile app authentication

查看:26
本文介绍了Rails api 和本机移动应用程序身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多关于这个主题的信息,但我找不到任何最新的信息.我看到诸如 这个与 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆