Facebook認証実装
質問
Facebook認証を完全に使用するプロジェクトに取り組んでいます(カスタム認証実装は存在しません)。プロジェクトは、サーバー側のスクリプトにPHPを使用します。高速で安全な認証メカニズムの実装を探しましたが、このテーマに関する詳細な説明は見つかりません。 Facebookのドキュメントは弱く、基本情報のみを提供しています。
どの認証方法が適切ですか? JavaScript SDKとPHP SDKがあります。私が理解しているように、私はログインにJavaScript SDKを使用する必要があります。その後、PHP SDKを使用して、資格情報の確認についてデータベースを確認します。ただし、PHP SDKでグラフAPIを使用すると遅いです。セッションを検証するより良い方法はありますか?
すべてのリクエストでセッションサーバー側(PHP-SDK)を確認する必要がありますか?
解決
私がアプリのためにやってくることは、私が見た他の方法と比較して、非常にシンプルで比較的速いです。
- signed_requestが存在する場合は確認してください。そうでない場合は、$ loginフラグをPHPで1に設定します
- ユーザーのセッション / Cookieをチェックして、ユーザーが以前にアプリによって認証されたかどうかを確認します(後でこれに戻ります。空の場合は、$ loginを1に設定します。
- ログインフラグが1に設定されている場合は、ユーザーをインストールURLに送信します。
- ユーザーはアプリをインストールし、コネクタページに送信されます。このページは、Access_Tokenを取得し、ユーザー用のセッション / Cookieを生成する目的を果たします。これは、ユーザーのセッションの存続期間中にこのAccess_Tokenの有効性を確認する必要がないことを意味します。 Offline_Accessも新しい機会を生み出します。 DBにAccess_Tokenも保存できます。
- Facebookに送信する電話があるときはいつでも、例外を確認してください。認証例外を押している場合は、ユーザーのセッションとCookieをクリアします。次回は、このプロセスがユーザーに見えなくても、Access_Tokenの更新を強制します。
私はアプリでこれを行いましたが、ほとんどの場合、Access_Tokenの有効性を確認するためにFBにクエリを作成する必要がないことも、各ページビューで常に取得する必要もありません。私たちの目標はアプリのレイテンシを減らすことでしたが、Facebookはレイテンシの最大の源であり、これを行うことで大幅に削減されました。
他のヒント
私自身の質問に答える:
Facebook認証が利用可能であることを確認するためにJavaScript SDKを使用しました。
- FB認証が問題なく、アプリケーションが認証されていない場合、ユーザーにFacebookの登録済みフォームを提示します。
- FB認証が問題ない場合は、Facebookログインボタンを表示します。
登録プラグインは私のアプリケーションを承認し、fblogin.phpに電話してPHP SDKを使用してこの情報を確認します。 PHP SDKが承認を検証すると、この情報をセッション変数に保存します。そのため、すべてのリクエストでFB認証を確認する必要はありません。
ログインボタンは登録プラグインと同じです。これらのメソッドは同じサーバー側の機能を共有しますが、表現は異なります。
Facebookのログアウトステータスをキャッチするために、JavaScript SDKを使用して、すべてのリクエストでFacebook認証を検証しました。ユーザーがログアウトされると、JSコードがfblogout.phpを呼び出し、現在のセッションが破壊されます。この方法には欠陥があります。ユーザーが私のWebサイトから明示的にログアウトしない場合、攻撃者は同じマシンでJSのみを無効にするユーザーに代わって何かをすることができます。
応答時間が速いより良いソリューションは見つかりません。
どちらか一方を使用できます。
PHP SDKを使用して、関連するURLを生成して人を送信できます。そして、それをリンクでワックしてください。または、JavaScriptを使用して、Facebookのデフォルトログインボタンを作成できます。
その後、どちらか一方を使用してセッションを維持および検証できます。
私は通常、PHPを使用してOAuthキーを使用してうなり声を上げ、JavaScript SDKを使用して、セッション監視のための素敵なFacebookボタンとマイナーではないグラフコールを作成します。
私がPHPにプッシュする重いグラフまたは複数のグラフコールを伴うもの。
しかし、そこにはあなたが望むことをする柔軟性があります。ログインにJavaScript SDKを使用する必要はありません。
すべてのページのロードを確認するかどうかは、あなた次第です。
私はJavaScript SDKを使用してそれを処理する傾向があり、セッションが死んだ場合はバークのように。ログアウトスクリプトへのページリダイレクトを呼び出します。
最新のバージョンの時点で、PHPとJS SDKは両方とも同じユーザーセッションにアクセスできるようになりました(JSでログインします また PHP [両方を行わなければならない代わりに])。チェックアウト このブログ投稿 より詳細な説明と例。
セキュリティが心配な場合は、セッションクッキーをより早く期限切れに設定することができます session_set_cookie_params().
まず、Access_Tokenだけでなく、理想的には、アクセストークンと一緒にユーザーのFacebook UIDを保存したいと思います。これは、通常、API呼び出しにアクセストークンと一緒にUIDを含める必要があるためです。
第二に、から Facebookのドキュメント
注:アプリケーションがOffline_Accessの許可を要求していない場合、アクセストークンは時間に縛られています。ユーザーがFacebookからログアウトすると、時間制限のアクセストークンも無効になります。アプリケーションがユーザーからoffline_access許可を取得した場合、アクセストークンには有効期限がありません。ただし、ユーザーがパスワードを変更するたびに無効になります。
第三に、Access_TokenとUIDを持っていることは、API呼び出しを実行することですよね?そこから始めます。 Access_Tokenのみが(どういうわけか)無効になる場合、認証を行います。 その時その有効かどうかを確認する方法は?さて、あなたはカールを使用できます(参照) また プロキシライブラリ(ただし、元々はCI用に書かれていたため、少し変更する必要がある場合があります)API呼び出しを検証プロセスとして作成します。サンプル(*ため息、プロキシライブラリを使用)...
// Suppose we are try to publish a status from our fb app
// $access_token hold the user access_token, which you saved into your database
// $uid hold the user facebook uid, which you saved into your database
$proxy = new Proxy;
// This is equal with perform regular HTTP POST request with cURL
$api_call = $proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));
// Now we can validate...
// If the API success, it will be returned a post id, with json format
// if not, it will be outputing json like...
// "{"error":{"type":"OAuthException","message":"Invalid OAuth access token."}}"
// so...
$result = (array) json_decode($api_call);
if(array_key_exists('error', $result))
{
// Here you can perform an oAuth authentification, to get fresh access_token and update your database
// ...
// After it done, process the previous api call with valid access_token
$proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));
}
Facebook Connectドキュメントはかなり限られています。それは本当にそれが何をしているのかをあなたに伝えるものではなく、それを行う方法だけです。私は個人的にどちらのSDKも使用していません。私は自分の開発プロジェクトのために独自のフレームワークを構築しました。
チュートリアルのJavaScriptと同様に、SDKの両方がIMOであり、かなり時代遅れです。
FB SDKの1つに固執したい場合は、私の提案です。グラフAPIクエリなどがAJAXを介してPHPバックエンドに送信された場合にのみ、JS SDKを使用します。それ以外の場合は、PHP SDKに固執します。
序章
FacebookはOAuth V2を使用しています。彼らは、2つの異なるフローの方法を説明しています...サーバー側とクライアント側。これは、OAuth V2サービスに対して認証されている他のアプリケーションと同じように実装されます。どちらも同じことをします。唯一の違いは、「コード」をrequest_typeとして使用して、将来トークンを取得するための承認コードを取得できることです。
認証
FB Connectが関係する限り、スクリプトが必要な場合は、認証が必要な場合はいつでもAuth TokenまたはAuthコードがあることを確認してください。あなたがそれを持っていないなら、あなたはそれを取得する必要があります。 FBボタンを表示する条件(ログインまたはログアウト)として、認証コードまたはトークンの存在を使用できます。
認証のためにユーザーをOAuthにリダイレクトします。 Facebookには、OAUTHの実装がダイアログAPIにバンドルされています。 OAuthダイアログの詳細については、こちら: http://developers.facebook.com/docs/reference/dialogs/oauth/
CSRF保護などのものには、オプションの状態パラメーターを使用できます。プロセス後に値を保持し、getパラメーターとしてコールバックで送信されます。
アプリケーションの相互作用
基本的に、通常と同じようにアプリケーションを書くことになります。違いは次のとおりです。
- ユーザーデータベースは、FB UIDだけでパスワードを保存しなくなりました。また、FB Dev TOSによると、ユーザー情報を実際に保存できません。ユーザー情報を保存する場合は、ユーザーから取得する必要があります。この情報をFB情報で入力することができます。送信するだけです。
- 登録方法には、Form EndEndの投稿はもうありません。認証されたユーザーがDBにエントリがない場合に呼び出されます。
APIインタラクション
トークンの代わりにコードを使用した場合は、コードを送信してトークンをリクエストする必要があります。これは、グラフAPI OAuthで行われます。この部分は、認証チュートリアル以外に文書化されていません。 http://developers.facebook.com/docs/authentication/
アクセストークンを使用すると、どちらの方法でも、取得するために使用できます。これで、必要なグラフAPIをクエリすることができます。これにより、JSONエンコードされたオブジェクトが返されます。
結論
高速で安全な実装に関する限り、Facebook PHP SDKがジョブを行います。 CSRFを含む、ここでカバーしたすべてを処理します。それを学ぶ方法は、まだまともなドキュメントを見つけていません。すべてが古いか、作家が本当に知らず、他のチュートリアルから外れています。
あなたの最善の策は、それらの図書館を深く掘り下げ、それがあなた自身のためにどのように機能するかを理解することです。試行錯誤を行い、実験してください。
私が学んだ方法は、自分のフレームワークを書くことでした。私はあなたが同じことをすることをお勧めします。必要に応じて、Facebook SDKクラスを拡張できます。それは本当に限られていますが、それはあなたが必要とするすべてをあなたに与えます。私は最も一般的に使用されるAPI呼び出しを取り、同様にそれらを入れました。私は今、私の図書館から駆動される非常に迅速でシンプルな最終結果を持っています。
SDKを実装する必要はないと思います。
1、ユーザーのデータにアクセスするには、ユーザーから許可を得る必要があります。したがって、それらをFacebookにリダイレクトする必要があります。 PHPのコードのわずか(3-5)ラインです。
https://graph.facebook.com/oauth/authorize?
client_id=YOUR_APP_ID&scope=email&redirect_uri=APP_URL
2、ユーザーがあなたのサイトに戻ったら、$ _get ['code']を持って来る
http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER
3、Facebook Get Requestを介してこのコードをデコードし、Access_Tokenを取得する必要があります。
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
3、Access_Tokenを持っている後、A /me?access_tokenは、必要な頻度でリクエストを取得し、ユーザーがまだそこにあることを確認します。
4、Facebook IDを保存できます。
これが最速の方法だと思います。私が知る限り、JavaScript SDKはポップアップを使用しているため、ほとんどのブラウザでブロックされています。
このフローはここで十分に詳細です: http://developers.facebook.com/docs/authentication/