GitHub で使われている Facebook の Delegated Account Recovery とは(概要編)

おはようございます、ritou です。

様々なご都合によりGitHubでTwo-factor authenticationってのを設定している方も多いでしょう。

時に人間は、記憶もスマホも財布も一気に無くしてしまいます。

リカバリー方法を複数用意しておくにこしたことはありません。

2019年7月時点の設定画面あたりのスクショはこんな感じです。

f:id:ritou:20190712022802p:plain

今回はこの中のRecovery optionsの一番下、「Recovery tokens」に注目します。

これ何だ?と思ってカーソルを当てると「Account recovery with Facebook is a simple way to recover your account.」とか出てきます。

f:id:ritou:20190712023201p:plain

今回はこの「Facebookでアカウントリカバリー」とは何かというお話です。

GitHub の機能を使ってみる

GitHubのヘルプに全部書いてあります。

これで満足していただけるようであればそれで良いと思いますが、一応書いてある通りやってみます。

リカバリーの設定

GitHubにて「Settings」->「Security」->「Two-factor authentication」->「Recovery tokens」と進みます。

f:id:ritou:20190712023945p:plain

この機能では 「お前のデータにアクセスはしないけど、こっちのサポートチームがお前のIdentityを検証するために使える。」 「まずはfacebook行って来い」 てなことが書いてあります。

Facebookに行ってみると何かの確認画面が出てきますが、いつものアクセス許可への同意画面とは何か少し違います。

f:id:ritou:20190712024354p:plain

「詳しくはこちら」の先も確認しましょう。

f:id:ritou:20190712024501p:plain

「いかがでしたでしょうか?」でまとめてくるブログ記事みたいな雰囲気のタイトルがついたヘルプページですが、基本的にデータはシェアされないことが書いてあります。

オンにすると設定完了です。

f:id:ritou:20190712024624p:plain

Githubに戻ってきました。

リカバリーの実行

GitHubを一旦ログアウトして、Facebookからリカバリーする手順を踏んでみましょう。

今度はFacebook側で「設定」->「セキュリティとログイン」->「外部アカウントのリカバリー」と進みます。

GitHubの設定があることがわかります。

f:id:ritou:20190715041734p:plain

リカバリーしてみます

f:id:ritou:20190715041823p:plain

(ここは人によりそうですが、私は2段階認証でSMSを設定しているせいか、確認が入りました。)

f:id:ritou:20190715042055p:plain

GitHubに遷移して...こんなメッセージが出てきました。

f:id:ritou:20190716024805p:plain

一発でログインさせるのではなく、サポートチームに「Facebookリカバリトークン使った復活をお願いします」と問い合わせてやってもらう流れです。

(おまけ)ちなみにもう一回試そうと思ったらこんなんなりました。

f:id:ritou:20190715042154p:plain

  終
制作・著作
━━━━━
ⓡⓘⓣⓞⓤ

この仕組み、標準化されたものではなくFacebookの独自のものです。Facebook側のドキュメントを見て仕組みを理解しましょう。

Facebookの仕様を理解する

ここですね。

developers.facebook.com

クローズドβということですが、GitHub以外に使ってるとこあるんでしょうか?なさそう?

概要

概要としては

  • パスワードや連絡先を失った場合のリカバリーに利用可能
  • OAuth/OIDCを用いたソーシャルログインとは異なり、ユーザー情報を共有しないシンプルな仕組み
  • メールやSMSへのコード送信よりもセキュア、連絡先変更時のトラブル回避にも使える

とあります。(私の場合、SMSの確認が入ったので若干気になるところもありますがこの辺は設定次第かもしれません。) 用途についても書いてますがとりあえずリカバリーです。

処理の流れ

登場人物は3者です。

  • Account Provider : Delegated Account Recoveryを利用するサービス (GitHub)
  • Recovery Provider : Delegated Account Recoveryを提供するサービス (Facebook)
  • User : GitHub / Facebookの両方にアカウントを持つユーザー

設定手順としては

  1. UserがAccountProviderにて認証済み or 新規登録中
  2. UserはAccountProviderにてサポートされているRecoveryProviderを選択
  3. AccountProviderはRecoveryTokenを生成、Userのブラウザ上でRecoveryProviderに送信 4 RecoveryProviderはUserにRecoveryTokenを紐付けて保存し、AccountProviderに戻る

という4ステップがあり、実行フローも

  1. Userはリカバリーが必要なことをAccountProviderに伝え、AccountProviderは紐づいているRecoveryProviderにUserをリダイレクト
  2. UserはRecoveryProviderにて認証される(リカバリ用途だとわかっているので、追加認証を求められる場合もある)
  3. RecoveryProviderはAccountProviderから受け取って保存していたRecoveryTokenを含むCountersignedTokenを生成し、Userのブラウザ経由でAccountProviderに送る
  4. AccountProviderはCountersignedTokenがRecoveryProviderからのものであることを検証、RecoveryTokenを検証したら内部のデータを複合化してUserをリカバリーします

という4ステップです。 シーケンスについては上記ページに記載してあります。

技術的なポイントとしては

  • 準備
    • OAuth/OIDCのClient登録的なものは必要なのか
  • 設定
    • AccountProvider(GitHub)が作るRecoveryTokenとはどんなものか
    • AccountProvider(GitHub)はRecoveryTokenをどのようにRecoveryProvider(Facebook)に送るのか
    • RecoveryProvider(Facebook)はRecoveryTokenをどのように扱うのか
  • 実行
    • RecoveryProvider(Facebook)が作るCountersignedTokenとはどんなものか
    • RecoveryProvider(Facebook)はどのようにしてCountersignedTokenをAccountProvider(GitHub)に送るのか
    • AccountProvider(GitHub)はCountersignedTokenをどのように検証するのか
  • 妄想
    • OIDCをシンプルにして同じことできないか

といったあたりが気になりますね。 書いてたらとても長くなって諦めたので、次回プロトコル編として公開したいと思います。

ではまた!