Upgrade to Pro — share decks privately, control downloads, hide ads and more …

実録!!Python Social Auth の Twitter OAuth API マイグレーションプロジェクトとその教訓

rocky
October 27, 2023

実録!!Python Social Auth の Twitter OAuth API マイグレーションプロジェクトとその教訓

PyCon APAC 2023の登壇資料です。
https://2023-apac.pycon.jp/timetable?id=FQLVVU

rocky

October 27, 2023
Tweet

More Decks by rocky

Other Decks in Programming

Transcript

  1. はじめに 本セッションでは、 実際に行った「Python Social Auth の Twitter OAuth API マイグレーション対応」を題材に、

    その背景や対応内容、結果、感想、学びなどなどについて共有してまいります。 - OAuth APIのマイグレーションを行う際に注意すべきポイント - 依存しているサービスやOSSの変更対処の考え方の一例 などをご提供できれば良いなと考えプロポーザルを出しました。 しかしながら....
  2. Python Social Auth の Twitter OAuth API マイグレーションプロジェクトとその教訓 ◆ 前提知識の共有

    ソーシャルログインや、今回の対応の背景情報について軽く触れつつ、 本セッションで題材にするシステム/サービスについてご紹介します。 ◆ 実録マイグレーションプロジェクト 無料API廃止アナウンス及びその後の動きに対するLAPRASでの対応について、 システム的な内容を含めてご紹介します。 ◆ 結果と振り返り 対応プロジェクトの結果や各局面における判断について振り返り、 今回得た学びを共有します。 ◆ まとめなど
  3. - Firebase Authentication - Auth0 - okta - Stytch -

    AWS Cognito ソーシャルログイン - 実装の選択肢 IDaaS等のサービスを利用 OAuthプロトコルを直接利用 https://github.com/joestump/python-oauth2 https://github.com/pennersr/django-allauth https://github.com/python-social-auth ◆ django-allauth ◆ python-social-auth ◆ python-oauth2 例 : 以下のようなライブラリが利用可能 例 : 以下のようなサービスが利用可能
  4. - Firebase Authentication - Auth0 - okta - Stytch -

    AWS Cognito ソーシャルログイン - 実装の選択肢 IDaaS等のサービスを利用 OAuthプロトコルを直接利用 https://github.com/joestump/python-oauth2 https://github.com/pennersr/django-allauth https://github.com/python-social-auth ◆ django-allauth ◆ python-social-auth ◆ python-oauth2 例 : 以下のようなライブラリが利用可能 例 : 以下のようなサービスが利用可能 今日のお話は python-social-auth にフォーカス システム的な課題については他のライブラリでも同じよ うな課題が発生しそうではあります。 (内部を軽く見た感想なので要出典です) 今回は触れませんが、 最近は直接利用よりもIDaaSを積極的に利用する流れが 強い印象です(私も同意です)
  5. Twitter API 騒動 2023.02.02 「1週間後の2月9日にAPIの無料アクセス廃止する よ」 EnterPriseなのに止まった! 2月9日になったのにアナウンスがない?? API v1.1死んだ?

    API使えなくなったのでサービス終了します ログインできなくなりました 落ちた!! 2023.07.24 「Xになったよ」 2023.08.22 「API v1.1も続々廃止していく よ」 なんか復活した? API制限でツイート見られない? 2023.01.xx 「昔からあるルールをちゃんと守っていないアプリはAPIアクセスをブロックする よ」 100$/月 !?? 対応完了しました
  6. 影響調査 2023.02.02時点では料金や必要な手順などの情報は一切不明であったため、 Twitter APIが一切使用できなくなることを想定して一次調査を実施した。 Crawler への影響 画面に表示するTwitterアカウントページへのリンク、 フォロワー数等の情報が取得できなくなる => 最悪許容するしかない

    ログイン・新規登録 への影響 Twitterによるログイン・新規登録ができなくなる => 最悪許容するしかない => ログイン手段がTwitterのみであるユーザはサービスにログインする手段を失う可能性があり、こ の事象は許容できない が、事後でもユーザの操作のみで救済できるルートが確率されている = メール アドレスによるログインを追加できる(※) ことを確認できたため、ケアができていると判断 ※サービス登録時、SNSによる認証であってもメールアドレスを入力する仕様があり、 このメールアドレスを指定してパスワードリセット操作を実行すると以後メールアドレスとパスワードでログインが可能
  7. 影響調査 - 事業数字周り 新規獲得への影響 => 軽微 注力ターゲット(当時) のうち、 Twitter広告経由かつTwitter連携で獲得できているユーザは全体の1% MAU

    / DAU => 軽微(+) 当月のアクティブユーザのうち、 Twitterが唯一のログイン手段であるユーザの割合は0.3%。 ※ただし、普段遣いでTwitterを用いているユーザがその他の手段を取ることが面倒になり... というケ ースは考えられる ※サービス登録時、SNSによる認証であってもメールアドレスを入力する仕様があり、 このメールアドレスを指定してパスワードリセット操作を実行すると以後メールアドレスとパスワードでログインが可能
  8. Crawler - API v2.0 を利用するように変更する - rate limit を上回る場合はplanを変更する (こちらもややこしい経緯がありますが今回は割愛します)

    ログイン・新規登録 - 対応しない - 厳密に言うとここについては自信を持てる状態ではなかった。 しかしながら、一時的なダウンは許容できるという評価と、仮に v1.1廃止に伴 う影響があるとしても局所対応が可能であると判断。 加えて、これまでの経緯からアナウンス通り対応したとしても影響無しで対処 しきれるとは考えられなかったため、事実が確定する事後対応のスタンスをと ることにした。 - 料金体系が変更される(無料 or 100$ or Enterprise) - API v1.1 が廃止される (これは誤解。最後に触れます) - OAuthAPI v1.0a は引き続き利用できる(廃止の報に含まれていない) 解釈 対応 方針
  9. A. python-social-auth を Twitter OAuth API v2.0 に対応させる B. アプリ側のマイグレーション課題の解決

    C. QA / リリース システム的対処 python-social-auth を題材にお話しますが、 おそらく同じようなところが問題になりそうな気がします
  10. OAuth2.0用の backendが無かったので これを実装 python-social-auth を Twitter OAuth API v2.0 に対応させる

    ここの実装についての詳細は割愛します。 [参考] https://github.com/python-social-auth/social-core/pull/791
  11. - 先々social-coreに破壊的変更が発生した場合に、リポジトリ内部においているコードは取り残され てしまう / 誰かが別の実装の TwitterOAuth2対応を行った場合ややこしいことになる - リポジトリに用意されたテストのヘルパー等を利用したテストを実行できる - contributionフローにのっとりつつ、メンテナのレビューを通ることで意識できていないリスクをあ

    る程度減らすことができる - 後述する、アプリ側のOAuthAPIのマイグレーション対応が開発負荷としては比重が大きく、こちら が早く終了しても対応完了は早くならない - mergeされない、リリースされない場合はそれがわかってからでもforkしたものを参照する/リポジ トリ内部でbackendを実装するという手段を取ることができる 手元のリポジトリ内部にオリジナルのバックエンドとして実装する選択肢はとらず、 あくまで本家に取り込んでもらうルートをベストシナリオとして対応した。 python-social-auth を Twitter OAuth API v2.0 に対応させる ここの実装についての詳細は割愛します。 [参考] https://github.com/python-social-auth/social-core/pull/791 OAuth2.0用の backendが無かったので これを実装
  12. - 先々social-coreに破壊的変更が発生した場合に、リポジトリ内部においているコードは取り残され てしまう - リポジトリに用意されたテストのヘルパー等を利用したテストを実行できる - contributionフローにのっとりつつ、メンテナのレビューを通ることで意識できていないリスクをあ る程度減らすことができる - 後述する、アプリ側のOAuthAPIのマイグレーション対応が開発負荷としては比重が大きく、こちら

    が早く終了しても対応完了は早くならない - mergeされない、リリースされない場合はそれがわかってからでもforkしたものを参照する/リポジ トリ内部でbackendを実装するという手段を取ることができる 手元のリポジトリ内部にオリジナルのバックエンドとして実装する選択肢はとらず、 あくまで本家に取り込んでもらうルートをベストシナリオとして対応した。 python-social-auth を Twitter OAuth API v2.0 に対応させる ここの実装についての詳細は割愛します。 [参考] https://github.com/python-social-auth/social-core/pull/791 OAuth2.0用の backendが無かったので これを実装 CTOならそれくらいやりなよ - 一緒にやるからさ という @yktakaha4氏からの温かいお声掛けもあり...
  13. social-auth-app-django social-auth-core LAPRAS アプリへの取り込み LAPRASからは「social-auth-app-django」を経由して利用している。 - [ ] masterマージ -

    [ ] リリース - ✅ masterマージ - [ ] リリース - [ ] 依存バージョン更新 PR作成から2weeksでマージしてもらえた(ありがたい)、 なかなかリリースはしてもらえなかった(しかたない) (直近は1回超/月はリリースされていたのに...)
  14. 課題 1 以前に Twitter OAuth v1.1 で登録/ログインしていたユーザが、 Twitter OAuth v2.0

    の認可フローを通ってログインを試みたとき、 別人として扱われ、新規登録フローにすすんでしまう
  15. python-social-auth では OAuth認可フローを通過した後の各処理が細切れに実装されている。 => pipeline functionと呼称 python-social-auth の構造 詳しくはコチラに https://zenn.dev/rocky_manobi/articles/438cd4f01166af

    pipeline function は 定義された実行順序の通りに実行される 各 pipeline functionが戻した値は次に実行される関数に 引数として渡されていく
  16. Appのログインセッションが活きていない場合 - UserSocialAuthというモデル(テーブルを) provider と uid をキーにして検索し、 既に存在しているかどうかを判定 - 存在する場合は「既存ユーザのログイン」と判定

    存在しない場合は「新規ユーザの登録」と判定 セッションが活きている場合 - UserSocialAuthというモデル(テーブルを) provider と uid をキーにして検索し、 現在ログインしているユーザと一致しているか否かを調べる - 一致していない場合は「既に他のユーザと紐づいている」エラーとする 原因と解決策
  17. Appのログインセッションが活きていない場合 - UserSocialAuthというモデル(テーブルを) provider と uuid をキーにして検索し、 既に存在しているかどうかを判定 - 存在する場合は「既存ユーザのログイン」と判定

    存在しない場合は「新規ユーザの登録」と判定 セッションが活きている場合 - UserSocialAuthというモデル(テーブルを) provider と uuid をキーにして検索し、 現在ログインしているユーザと一致しているか否かを調べる - 一致していない場合は「既に他のユーザと紐づいている」エラーとする Twitter OAuth API v1.0a の場合の provider は “twitter” Twitter OAuth API v2.0 の場合の provider は “twitter-oauth2” 検索キーとなる値が異なるため、 常に新規作成ユーザ と扱われてしまっていた 原因と解決策
  18. 課題 2 こういうやつ.... SNSサービス と OAuth Provider は別のもの。 名前がたまたま同じだからといって同じように扱うと痛い目を見るという典型。 provider名

    => SNS名 の読み替えを行う機構を作って対処。 (サービスの性質上利用箇所が多岐にわたっており...) どのようなライブラリ / サービスを利用していても、このような箇所がないかどうか はチェックしたほうが良さそうです。
  19. Twitterログイン機能の早期復旧を目指さない選択肢は正解だったのか? 感想戦 - 1 2023.08.22 「API v1.1も続々廃止していく よ」 選ばなかった世界線の評価は難しいところではあるけれど、正解と考えている。 結果としてトラブル無く対応を完了できたことや、

    対応完了後にアナウンスされた API v1.1 を廃止するというアナウンスに反応しなくて済み、 普段の開発を継続できている。 このさきOAuth API v1.1a が廃止される日が来たとしても対応済みとして構えることができる。 やってわすれる。大事。
  20. 廃止アナウンスに対する構えは隙だらけだった 最悪を想定して調査/見積もりを行うことはできていた。 本当に最悪が起こるとしてやるべきことを考えていない楽観思考があった。 Twitter関連機能をフラグ操作1つでクローズできるような仕組みを構築する程度 の対応は行われてしかるべきだった。 (要因は色々考えられますが飲み会とかでお話しましょう) 感想戦 - 2 Twitterのアナウンスが信用できない

    / 何が起こるかわからない と言っておきながら、 「ここは影響がなさそう」という楽観材料については信じてしまう心の弱さが強く出ていた? 機能としての重要度がそこまで高くないという背景と、結果論的には問題がないとは言えることと、 当時のことは記憶をたどることしかできないので、このあたりは次にこのような状況があったときに自 問できるようにしておこうとおもう。
  21. 感想戦 - 3 そもそもTwitter API についての理解が圧倒的に足りていなかった 今回の対応には少なくとも以下の単語について、 意味合い、役割、関係を理解した上で望む必要があったはず。 Essencial, Standard,

    Premium, Elevated, basic, pro, free, enterprise, API v1, API v1.1, API v2 OAuth API v1.0a , OAuth API v2.0 これらを理解した上で改めてアナウンスを追いかけると、 我々は途中で直面したトラブルの原因を多く見誤っていたことが分かった。 そしておそらく我々と同じく多くの人が同じような誤解をしていたと考えられる。 例えば … 少なくともX(Twitter)は 2023.08.22 まで、 API v1.1 を廃止するというアナウンスはしていない(名指しした特定のAPIを除いて)。 にもかかわらず ….. つづきは口頭で!
  22. 感想戦 - 3 そもそもTwitter API についての理解が圧倒的に足りていなかった 今回の対応には少なくとも以下の単語について、 意味合い、役割、関係を理解した上で望む必要があったはず。 Essencial, Standard,

    Premium, Elevated, basic, pro, free, enterprise, API v1, API v1.1, API v2 OAuth API v1.0a , OAuth API v2.0 これらを理解した上で改めてアナウンスを追いかけると、 我々は途中で直面したトラブルの原因を多く見誤っていたことが分かった。 そしておそらく我々と同じく多くの人が同じような誤解をしていたと考えられる。 例えば … 少なくともX(Twitter)は 2023.08.22 まで、 API v1.1 を廃止するというアナウンスはしていない(名指しした特定のAPIを除いて)。 にもかかわらず ….. つづきは口頭で! 雰囲気で触るというのはとても危ない 強い気持ちで使っているものを理解している状態を目指そう