簡體   English   中英

Rails api和本機移動應用程序身份驗證

[英]Rails api and native mobile app authentication

我知道有很多關於這個主題的信息,但我找不到任何最新的信息。 我看到這樣的主題與rails和android身份驗證有關,但我看到TokenAuthenticatable現在從設計中刪除了

我的問題很簡單:有沒有一種很好的方法來使用Rails 4從本機Android和iPhone應用程序驗證用戶? 有沒有人知道提供解決方案的好教程或文章?

Adam Waite添加賞金:

我剛剛在這個問題上開了一個500賞金,因為我找不到在任何地方從iOS應用程序到Rails API驗證用戶的正確做法。 這是我考慮做的事情,但不知道它是否安全?!:

我們假設我們有一個User記錄。 用戶已注冊一個帳戶,該帳戶已使用email列和password_digest列在數據庫中創建了User記錄。

當用戶登錄時,我希望該用戶在移動應用程序上保持身份驗證,直到明確注銷。

我想我們將需要基於令牌的身份驗證。 我可能會在創建User時創建一個ApiKey記錄,並將其保存為User記錄上的關聯。

當用戶登錄/注冊時,響應將包含一個API令牌(類似SecureRandom.hex ),它將保存在iOS Keychain中,並與所有后續請求一起使用,通過將其傳遞到標頭並使用它驗證來驗證用戶就像是:

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到最佳答案。

我的研究解決方案的要點。 隨意編輯,更正,無效等。

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

您處於正確的軌道上,但用戶的令牌應僅用於識別發出請求的用戶。 您仍然需要某種身份驗證,因為當您推測在每個請求上更改令牌時,黑客可以攔截數據流,獲取令牌,然后在后續請求中“成為”該用戶。

通過更改每個請求上的令牌,您可以消除攔截問題,但是一旦有人攔截了令牌,他們就可以通過繼續攔截它甚至修改響應來進一步利用系統。 對此的一個解決方案是使用HMAC(由Amazon Web Services使用)。 它是一種算法,為您的請求提供簽名(哈希),該簽名對於每個請求都是唯一的,不需要更改密鑰,也不能為將來的請求進行預測。

有一個用於rails的ruby gem,它在服務器端實現HMAC,用於簽署HMAC請求,以及在進行服務器到服務器通信時生成它們。 對於客戶端到服務器請求,您需要在iOS或Android端生成簽名並在服務器上對其進行身份驗證。

考慮ApiAuth gem在服務器端進行工作。 在iOS客戶端,考慮HBHMAC庫以生成簽名。 看看ApiAuth的具體實現,因為它為數據添加時間戳以防止重放攻擊,因此您可能需要在將數據傳遞給HBHMAC之前為其添加字段。

總之,使用HMAC身份驗證將通過利用單向散列算法避免人員處於中間攻擊和重放攻擊,該算法可防止攻擊者生成真實請求,即使他們能夠攔截有效請求。

我遇到過這個問題,我是一名API開發人員。 可以通過令牌和自定義授權完成這項工作,但我會告訴您我們如何處理我們的應用程序,該應用程序以六位數的形式為用戶提供服務。

至少對於iOS,設備將為您處理會話,這意味着如果iOS應用程序上的用戶向/users/sign_in帶有參數的POST請求

user: { 
  password: 'mypassword',
  email: 'testuser@example.com',
  remember_me: true # optional
}

iOS設備將安全,持久地為您存儲會話。

現在,如果你想進入OAuth 2路線,我實際上為rails 4維護了一個名為OAuth 2 providable的gem,我添加了一個非常酷的功能,允許你讓用戶通過“授權”屏幕,因為很明顯如果您開發了該軟件,則無需用戶確認他們信任您。

如果您決定使用OAuth 2,則需要使用調用隱式訪問令牌的內容。 這對於長期和無聊的OAuth2規范

rails 4項目可以在github上找到https://github.com/bwheeler96/devise-oauth2-provider-rails4

如果您不在rails 4上,則可以使用原始gem https://github.com/socialcast/devise_oauth2_providable

順便說一句,寶石需要工作,所以如果有人讀這個想要幫助它做得更好的人,請務必分叉這個存儲庫

如果你想在rails上的ruby中使用OAuth2.0,你可以使用Doorkeeper,你可以在這里看到一個例子(不是免費的):

http://railscasts.com/episodes/353-oauth-with-doorkeeper

但你可以使用一個帶有SecureRandom.hex的令牌,這里有一個例子(不是免費的)(在第6級):

https://www.codeschool.com/courses/surviving-apis-with-rails

我希望我的回答對你有所幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM