このトピックについて多くの情報があることは知っていますが、最新の情報は見つかりません。 RailsおよびAndroid authentication に関連するこのトピック)のようなトピックが表示されますが、- TokenAuthenticatable
はdevise から削除されました。
私の質問は単純です。ネイティブAndroidおよびRails 4を使用するiPhoneアプリ)からユーザーを認証する良い方法はありますか?ソリューションを提供しますか?
Adam Waiteバウンティの追加:
IOSアプリからRails APIへのユーザー認証の正しい方法を見つけることができないため、この質問で500バウンティを開きました。これは私が検討していたことですが、安全かどうかわかりません!:
User
レコードがあるとします。ユーザーが、User
列とpassword_digest
列を持つemail
レコードをデータベースに作成したアカウントにサインアップしました。
ユーザーがサインインするとき、明示的にサインアウトするまで、そのユーザーをモバイルアプリで認証されたままにします。
トークンベースの認証が必要になると思います。 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。
私の研究からの解決策の要点。自由に編集、修正、無効化などしてください。
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 [Controllers&Models] https://github.com/danahartweg/ authenticatable_rest_api
私はこの問題を抱えていました。私はAPI開発者です。あなたはできますトークンとカスタム認証で難しい方法を実行しますが、6桁のユーザーにサービスを提供するアプリケーションで何をするかを説明します図。
少なくともiOSの場合、デバイスはセッションを処理します。つまり、iOSアプリのユーザーがPOSTに/users/sign_in
パラメータ付き
user: {
password: 'mypassword',
email: '[email protected]',
remember_me: true # optional
}
iOSデバイスは、セッションを安全かつ永続的に保存します。
ここで、OAuth 2ルートに移動したい場合、実際にはRails 4と呼ばれるOAuth 2提供可能です。ユーザーに「認証」画面を通過させるためのかなりクールな機能を追加しました。ソフトウェアを開発した場合、ユーザーがユーザーを信頼していることを確認する必要がないことは明らかです。
OAuth 2を使用する場合は、暗黙のアクセストークンと呼ばれるものを使用する必要があります。 これは長く、非常にそのための退屈なOAuth2仕様
Rails 4プロジェクトはgithubにあります https://github.com/bwheeler96/devise-oauth2-provider-Rails4
Rails 4でない場合は、元のgemを使用できます https://github.com/socialcast/devise_oauth2_providable
ちなみにgemには作業が必要なので、これを読んでもっと良くしたい人がいたら、ぜひフォークしてください this repository
順調ですが、ユーザーのトークンは、どのユーザーがリクエストを行っているかを識別するためにのみ使用する必要があります。要求ごとにトークンを変更することで推測すると、ハッカーはデータストリームを傍受し、トークンを取得して、その後の要求でそのユーザーを "利用"できるため、依然として何らかの認証が必要です。
リクエストごとにトークンを変更することで、インターセプトの問題を排除できますが、誰かがトークンをインターセプトすると、トークンをインターセプトし続け、レスポンスを変更することで、システムをさらに悪用することができます。これに対する1つの解決策は、HMAC(Amazon Webサービスで使用される)を使用することです。これは、すべてのリクエストに対して一意であり、変更キーを必要とせず、将来のリクエストに対して予測できない、リクエストに署名(ハッシュ)を提供するアルゴリズムです。
Ruby gem for Railsこれはサーバー間でHMACを実装し、サーバー間通信を行うときにHMAC要求に署名するためにそれらを生成する)があります。あなたの場合のようにクライアントからサーバーへのリクエストの場合、iOSまたはAndroid側で署名を生成し、サーバーでそれらを認証する必要があります。
ApiAuth gemをサーバー側で処理することを検討してください。 iOSクライアント側では、署名を生成するために [〜#〜] hbhmac [〜#〜] ライブラリを検討してください。 ApiAuthの特定の実装を確認してください。リプレイ攻撃を防ぐためにデータにタイムスタンプが追加されるため、HBHMACに渡す前にデータにフィールドを追加する必要がある場合があります。
要約すると、HMAC認証を使用すると、攻撃者が有効な要求を傍受できたとしても、攻撃者が本物の要求を生成できない一方向ハッシュアルゴリズムを利用して、中間者攻撃とリプレイ攻撃を回避できます。
OAuth2.0をRuby on Railsで使用する場合は、Doorkeeperを使用することになります。ここに例(無料ではありません)を示します。
http://railscasts.com/episodes/353-oauth-with-doorkeeper
ただし、SecureRandom.hexでトークンを使用できます。これの例(無料ではありません)は次のとおりです(レベル6)。
https://www.codeschool.com/courses/surviving-apis-with-Rails
私の答えがあなたを助けることを願っています!