Laravel SocialiteでTwitter連携

はじめに

OAuth認証使うと、大概認証後リダイレクト時の担保として、認証処理が自分たちのサイトから要求がかかったものなんだっけ?
というのを検証しないといけないです。
以前もこの件調べたのですが、最近Twitter連携を作ったら完全に忘れてたので、今後2度と調べないために残しておきます。

前提

最近ポリシーが変わって取るのが大変みたいなのを見ますが、
個人開発には当てはまらない模様。
申請したら秒速で承認されたので、多分チェック入らないです。

  • Laravelのバージョンは何でもOK(手元は5.5系、socliaiteは3.0)

結論

いきなり結論なのですが、マルチテナントで動くようなアプリでない限りは、
Laravel SocialiteのデフォルトProviderに組み込まれているTwitterProviderをそのまま使えば問題ないです。

TwitterProvider::redirectメソッドを呼ぶと、oauth.tmpをキーとしてセッションにrequest token secret相当のものが保存されます。
TwitterProvider::userメソッドでTwitterカウントの情報を取るときに上記oauth.tmpに保存された情報を使いながら、よろしくやってくれるという具合です。
とても便利。

マルチテナントなシステムだとどうするのか?

Twitterのアプリ設定でコールバックURLは1つしか持てないので、
共通のリダイレクト先を経由させて、テナントごとのURLに戻してやる必要があります。
流れ的には以下です。

  1. TwitterProvider::redirect()の戻り値(\Symfony\Component\HttpFoundation\RedirectResponse)を使ってgetTargetUrl()のクエリストリング取得
  2. oauth_tokenパラメータが、セッション(キー:oauth.tmp)に保存されたidentifierの値なので、
    それをキーにしてテナントごとの戻り先コールバックをセッションやKVSに保存
    (私はRedisにタイムアウトまで指定して保存している)
  3. 共通リダイレクトのコントローラで、リクエストのクエリストリングに設定されたoauth_tokenを使って、テナントごとの戻り先コールバックを取って、リダイレクトさせる
    このときクエリストリングも一緒に付与する。
    そうしないと、TwitterProvider::userメソッドをコールした場合に、クエリストリングにoauth_verifierがあるかチェックを行ってなければエラーにされてしまいます。
  4. テナントごとの戻り先コールバックでTwitterProvider::userメソッドをコールすれば必要なモノが取れます。

2で、oauth.tmpを使ってないのは、テナントごとに見えるセッションを変えているため、共通リダイレクト先でテナントごとシステムのセッション情報が見えないため。 (隣のテナントなんかURL判らないと思うけど、一応そういう配慮はしている)

その他

以前は1度ツイッター連携したら、次回からは認証画面が出なかったけど、今は毎回聞かれるようになってました。
ので、socialite/twitterパッケージ使う必要がなくなった感がある。(もともと私は使ってないけど)

おわりに

Laravel SocliateでTwitter連携する場合は、Request Token Secretはライブラリ内部でよろしくやってくれる。 マルチテナント環境の場合は、リダイレクトのパラメータに含まれているoauth_tokenをキーにして、テナントごとのURLにリダイレクトしてやると良い。