質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Facebook Graph API

Facebook Graph APIとは Facebookのグラフデータベース用のAPIであり、対応言語はPHP、Perl、ActionScript、JavaScriptなどがあります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

1回答

5271閲覧

FacebookSDK for PHPでFacebook認証を実装したいがCSRF検証で引っかかる

YorihiroKatsuki

総合スコア70

Facebook Graph API

Facebook Graph APIとは Facebookのグラフデータベース用のAPIであり、対応言語はPHP、Perl、ActionScript、JavaScriptなどがあります。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Facebook

Facebookは、実名登録制のSNS(ソーシャル・ネットワーキング・サービス)です。開発者用のデベロッパーサイトが存在し、一般ユーザーによるFacebook向けアプリケーション開発が可能です。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

0クリップ

投稿2016/11/27 16:02

###前提・実現したいこと
Facebook for PHPでFacebookログインを実装したいと考えています。
フレームワークはLaravelを使っており、開発環境はcloud9です。
(ちなみにlaravelのパッケージSocaliteは試しましたが別のエラーがどうしても修正出来ず諦めてこちらのSDKを使っております)

機能の流れとしては、FacebookSDKforPHPのスタートガイドにあるように、
・Facebookログイン用のURLを取得する
・URLにアクセスするとfacebook側の認証ダイヤログが出て、ID/PASSを入力して承認すると、設定したコールバックURLにリダイレクトする
・リダイレクトされたらアクセストークンを取得しセッションに保存する
という感じで実装しています。

###発生している問題・エラーメッセージ
Facebookログインのリンクをクリックすると、facebook側の認証画面が出て、ID/PASSを入れ承認すると以下のようなエラーが発生します。

FacebookSDKException in FacebookRedirectLoginHelper.php line 246: Cross-site request forgery validation failed. Required param "state" missing from persistent data.

CSRFの検証の部分でパラメータの"state"が無いよと言われているようです。

コードをたどっていくと、
FacebookRedirectLoginHelperクラスのvalidateCsrfメソッド内にある、

$savedState = $this->persistentDataHandler->get('state');

の中身がnullになっており、
多分セッション?にあるはずのstateというパラメータが無いために、CSRFの検証が出来ずエラーになっているようです。

ただ、同じFacebookRedirectLoginHelperのmakeUrlメソッド内でログインURLを作成する際に、以下のコードでstateをセッション?に保存しています。
(pesistentDataが永続データというのは分かるのですがこれがどこに保存されているのかよく分かっていません)

$state = $this->persistentDataHandler->get('state') ?: $this->pseudoRandomStringGenerator->getPseudoRandomString(static::CSRF_LENGTH); $this->persistentDataHandler->set('state', $state);

この時点で$stateにランダムな文字列が格納されているのは確認済みです。

なので、ログインURLを作成した際に保存した"state"がログインURLをクリックして認証を終えて戻ってきたら消えていた、みたいなことかな、と考えていますが、原因が全くわかりません。

ちなみに、承認後facebookから返ってくるURLはこんな感じです。

https://emerge0-yorinton.c9users.io/auth/login/callback/facebook?code=xxxxxxxxxxxxxxx&state=xxxxxxxxxxxx#_=_

(codeとstateの値は読みやすさのために短くしています)
なので、コールバックURLにはちゃんとパラメータstateがついているので、後はそのpersistentDataにstateがあって、2つのstateが一致するばCSRF検証通過、ということかな、と考えています。

こちらについて原因・解決策が分かりましたら教えていただけますと幸いです。

###補足情報(言語/FW/ツール等のバージョンなど)
・言語:PHP
・フレームワーク:Laravel
・開発環境:cloud9
・FacebookSDKのバージョン:v2.8

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Facebook\Helpers\FacebookRedirectLoginHelper はCSRF対策のため、セッションを利用するので、事前にセッションの利用を開始しておく必要があるらしいです。
http://qiita.com/AtsukiTak/items/dfadaaea45df8007f801

laravelのSocialiteであればGithub用ですけどこんな感じでやってますので何か参考になれば幸いです

PHP

1Route::get('/stars/', function (Request $request) { 2 3 #トークンの取得をクッキーから試みる 4 $github_token = $request->cookie('github_token'); 5 $user_name = $request->cookie('user_name'); 6 #トークンがクッキーに設定されていなければ 7 if(!isset($github_token) || !isset($user_name)){ 8 #Githubからのコールバックでトークンの取得を試みる 9 try{ 10 $user = Socialite::driver('github')->user(); 11 } catch (Exception $e) { 12 #GithubからのコールバックでなければユーザーをGithubへリダイレクトして 13 #ユーザーにトークンの発行許可をしてもらう 14 return Socialite::driver('github') 15 ->redirect(); 16 } 17 #トークンを取得して、次回以降も再利用するためにクッキーに設定する 18 $github_token = $user->token; 19 $user_name = $user->getNickname(); 20 Cookie::queue(Cookie::make('github_token', $github_token, 60*24*30)); 21 Cookie::queue(Cookie::make('user_name', $user_name, 60*24*30)); 22 } 23 24 #取得したトークンを使用してユーザーのお気に入りのリポジトリリストをGithubから取得する 25 $client = new Client();//use GuzzleHttp\Client; 26 $query = [ 27 'per_page' => '100', 28 ]; 29 try{ 30 $res = $client->get('https://api.github.com/users/'.$user_name.'/starred', [ 31 'query' => $query, 32 'headers' => [ 33 'Authorization' => ' token '.$github_token, 34 ] 35 ]); 36 } catch (Exception $e) { 37 #取得に失敗したのでトークンが無効になったものだと想定して、 38 #クッキーに保存されているトークンを削除して再発行する 39 Cookie::queue(Cookie::forget('github_token')); 40 Cookie::queue(Cookie::forget('user_name')); 41 return Socialite::driver('github') 42 ->redirect(); 43 } 44...

投稿2016/11/27 17:24

cat_breed

総合スコア123

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YorihiroKatsuki

2016/11/28 04:29

ありがとうございます! Laravelを使っているのでセッションは問題無さそうでしたが、一応session_start()をログインURL作成時とコールバック時に入れてみましたがダメでした。 ただSocialiteでTwitterログインを試してみようと思い、試したところ、confg/services.phpに加えてfacebook、twitterが反映されていないことに気づきました。 原因は以前configをキャッシュしていて、そのキャッシュの方をずっと見ていたためです。 もう一度php artisan config:cacheをするとうまくいきました! こんな簡単なことに気づかずお手数おかけしてしまいすみません。 ご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問