事象
Socialiteを使ってソーシャルログインを実装したのだが、callback URLをリクエストする際にエラー発生。
厄介なのは認証する人のSNS側のパーミッション設定(ブラウザ?)によってエラーになったりならなかったりする。
Laravel \ Socialite \ Two \ InvalidStateException
環境
- Laravel 5.7
- Socialite 3
結論
プロバイダーからユーザー情報取得時にステートレスにすることで解決。
// Socialite::driver($provider)->user();
Socialite::driver($provider)->stateless()->user();
セッションの問題
ソースコードを見ると、セッションからstateっていうのをとってくるんだけど、それがnullの場合にエラーになるっぽい。
/**
* Redirect the user of the application to the provider's authentication screen.
*
* @return \Illuminate\Http\RedirectResponse
*/
public function redirect()
{
$state = null;
if ($this->usesState()) {
$this->request->session()->put('state', $state = $this->getState());
}
return new RedirectResponse($this->getAuthUrl($state));
}
で、セッションの設定を見るとenvから読み込んでいる。
'domain' => env('SESSION_DOMAIN', null),
というわけで当初、このあたりの記事を参考にさせていただきドメインをenvに登録するも直らず。
https://qiita.com/chtzmrtshgh/items/84817942255d3d5dff45
SESSION_DOMAIN=hogehoge.com
また、私の環境ではサブドメインでも同じ機能を参照しており、「hogehoge.com」「s.hogehoge.com」など複数ドメインで運用する環境ではうまくいきませんでした。
##セッション無効にするオプションはないものか
そもそも不安定なセッション取得を必須にしなくてもいいよね。
と思ったらありました。
ガイドに書いてあるとおり、ステートレスな認証を使うことで解決。
https://readouble.com/laravel/5.7/ja/socialite.html
statelessメソッドはセッション状態の確認を無効にするために使用します。これはAPIへソーシャル認証を追加する場合に便利です。
return Socialite::driver('google')->stateless()->user();
結論
公式とかちゃんと読もう。