Rails APIを構築しており、ユーザーがOmniauth Identityを使用して認証する方法を正常に構築しました。
クライアントから単にauth/identity/callbackに投稿し、auth_keyとパスワードを渡します。
その後、サーバーはドアキーパートークンを返します。このトークンはその後、ユーザーがアプリにアクセスして自分自身を識別するために使用します。
この図はこれを示しています:
クライアントからFacebookログインを実装したいのですが、理論的にも実際的にも、それを機能させるのに苦労しています。
単純なRails Omniauth Identityのアプリでは、auth/facebookを呼び出すだけですが、これにリンクをクライアントに配置すると、サーバーが呼び出され、サーバーがログに記録します。
INFO -- omniauth: (facebook) Request phase initiated.
アプリはFacebookでIDとシークレットを使用して正しくセットアップされているので、ログインプロンプトがサーバーに返されるのでしょうか。
認証を連鎖させても混乱しています。どんな助けもありがたいことに感謝します!
私が見つけた最良の方法は(この問題でしばらくの間立ち往生した後)、あなたのomniauth2を行うことです(特に私の場合は satellizer angular plugin)を使用して手動で。 。
私の場合はFacebookのソリューションについて説明しますが、他のプロバイダーにもすべて適用できます。
最初にomniauth2がどのように機能するかを知る必要があります( ここで人間のために文書化されています )...
code
(認証コード)クエリ文字列パラメーターリダイレクトバックURLは、バックエンドURLではなく、フロントエンドアプリのURLと一致する必要があり、Facebookアプリの構成で指定する必要があります
code
パラメータは、ポップアップを開いた親ウィンドウに送り返されます。POST
パラメーターを使用してcode
要求をbackend/auth/facebook
に送信します。code
(認証コード)が交換されます access token
ここで、 facebook developer documentationからcode
をaccess-token
に交換する方法を詳細に説明します。
Server:ステップ6で取得したaccess-token
を使用ユーザーの情報を取得します。
VOILAあなたは自分自身に他のoauthプロバイダーなどとアカウントをマージ/作成/リンクすることができますが、ユーザーはemail、facebookは許可の一部の取り消しをサポートしています)...
(話して、コードを見せてください)
まず、GemfileにHTTParty gemを追加する必要があります
gem 'httparty' # Makes http fun again (http client)
this Gist を追加しました。これには、ステップ(6、7、および8)のフローが含まれます。これらは最も問題のあるステップであり、ほとんどどこにも文書化されていません。
gistは2つの主な方法をエクスポートします。
Omniauth::Facebook.authenticate(authorization_code)
facebookでユーザーを認証し、user_info、long_live_access_tokenを返すために使用されます(60日間有効)
Omniauth::Facebook.deauthorize(access_token)
これは、facebookのaccess_tokenおよびアプリケーション許可の認証解除/取り消しに使用されます...
これは、ユーザーがfacebookログインで要求された電子メール許可を取り消すときの特別な要件に使用されます...アプリケーション全体の許可を取り消します...これにより、ユーザーは最初のログインであるかのように次のログインでプロンプトが表示されます(不要) Facebookアプリに移動して、アプリケーションを手動で取り消すには)...
コントローラーでの使用方法は次のとおりです
user_info, access_token = Omniauth::Facebook.authenticate(params['code'])
if user_info['email'].blank?
Omniauth::Facebook.deauthorize(access_token)
end
これで...実装の内部に興味があるなら... Gistに見られるコードはここにあります。 (参照用に追加)自由にフォーク、編集、改善を支援してください。
require 'httparty'
module Omniauth
class Facebook
include HTTParty
# The base uri for facebook graph API
base_uri 'https://graph.facebook.com/v2.3'
# Used to authenticate app with facebook user
# Usage
# Omniauth::Facebook.authenticate('authorization_code')
# Flow
# Retrieve access_token from authorization_code
# Retrieve User_Info hash from access_token
def self.authenticate(code)
provider = self.new
access_token = provider.get_access_token(code)
user_info = provider.get_user_profile(access_token)
return user_info, access_token
end
# Used to revoke the application permissions and login if a user
# revoked some of the mandatory permissions required by the application
# like the email
# Usage
# Omniauth::Facebook.deauthorize(access_token)
# Flow
# Send DELETE /me/permissions?access_token=XXX
def self.deauthorize(access_token)
options = { query: { access_token: access_token } }
response = self.delete('/me/permissions', options)
# Something went wrong most propably beacuse of the connection.
unless response.success?
Rails.logger.error 'Omniauth::Facebook.deauthorize Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.deauthorization'
end
response.parsed_response
end
def get_access_token(code)
response = self.class.get('/oauth/access_token', query(code))
# Something went wrong either wrong configuration or connection
unless response.success?
Rails.logger.error 'Omniauth::Facebook.get_access_token Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.access_token'
end
response.parsed_response['access_token']
end
def get_user_profile(access_token)
options = { query: { access_token: access_token } }
response = self.class.get('/me', options)
# Something went wrong most propably beacuse of the connection.
unless response.success?
Rails.logger.error 'Omniauth::Facebook.get_user_profile Failed'
fail Omniauth::ResponseError, 'errors.auth.facebook.user_profile'
end
response.parsed_response
end
private
# access_token required params
# https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3#confirm
def query(code)
{
query: {
# The authorization_code we want to exchange for the access_token
code: code,
# This must match the redirectUrl registerd in the facebook app.
# You can save it to ENV['WEB_APP_URL'] if you have multiple facebook apps for development and testing
# so you can support testing app on development and production app on production env.
redirect_uri: "http://localhost:9000/",
client_id: ENV['FB_APP_ID'], # Facebook appId
client_secret: ENV['FB_APP_SECRET'], # Facebook app secret (must not exist on front-end app for security)
}
}
end
end
end
ここにもう1つあります instagramのoauthを実装するnodejsチュートリアル oauth2の動作を理解するのに役立ちました(参照用に追加)
この問題を解決するために私が見つけた最良のリソースは、サテライザーgithubリポジトリのRailsサンプルアプリケーション: https://github.com/sahat/satellizer/tree/master/examples/server/Ruby
サテライザーコードは AuthController.authenticate メソッドを呼び出します。このメソッドは 各プロバイダーのoauthモデルクラス を使用して、受け取ったコードをアクセストークンに変換します。次に、 ser class で、プロバイダーから取得した情報に一致するユーザーを取得できます。
最後に、コントローラーメソッドはjwtトークンをクライアントに返します。
私の場合、メール/パスワード認証にもdeviseを使用していますが、コントローラー部分は少し異なりますが、th oauthクラスをそのままコピーし、魅力のように機能します。
Facebook apiとの通信へ。 'omniauth-facebook' gem を使用することをお勧めします。この例を複製して、さらに理解することができます。 https://github.com/ralphos/omniauth-facebook-example