ID連携を実装する際はキャンセル時の挙動も確認しよう
ritou です。
いわゆる OAuth Dance と呼ばれる、外部アカウントやリソースとOAuth/OIDCを用いた連携処理を行う際に、リソースオーナー/エンドユーザーと呼ばれる利用者の許可を求める処理があります。
TwitterやFacebookなどでは、ID連携の要求をキャンセルすることができます。
Twitterの"連携アプリを認証" っていう日本語もかなりアレですが、そこは触れずにいきましょう。
今日はなんの話かというと、個人開発や有名どころのライブラリを使わず自前で実装するようなケースで、このID連携時にユーザーがキャンセルした場合の挙動がお粗末なケースが目につきますのでちょっと書いておきます。
ID連携キャンセルは起こり得る動作である
キャンセルとはどのような意図で行われるのでしょうか。
- 使うのやめた : TwitterでDM見れる権限を要求するサービスなんて使わない
- 連携してるのは別のサービスのアカウントだった : あっ、ここはTwitterアカウントじゃなくGoogleアカウントでログインしてたんだった
みたいな場合、普通にキャンセルは起こりえます。 よって、このハンドリングも正しく行えるようにしておく必要があります。
よくない例
どこかのサービスを叩きたいのが目的ではないので汎用的に書いておきたいところですが、
- エラーメッセージそのまま出しちゃう
- 内部のエラーメッセージ出しちゃって意味わからん
- 白い画面にダメだったっぽい文字列だけ出る
- 変なログインセッションできちゃう
みたいなのを目撃したことがあります。
1は酷いものは error
パラメータをそのまま表示していて、クエリ改竄によりなんらかの攻撃につなげられてしまうのではないかみたいな例もありました。2はそれが改善されたものの...って感じですね。
3は某開発者向けカンファレンスでもあった事象ですが、この辺りの挙動となるとWebアプリケーションフレームワークとかの話になるのかもしれません。
4ぐらいになるとちょっと心配です。
いずれにせよ、比較的大きなサービスでQAが行われるようなところでは指摘が入ってなんらかの対応が行われそうな印象があるので、そうではない個人開発とかの方で気をつけてもらう方が良いのかなというところです。
良い例
このID連携のキャンセル時には、ID連携を要求する側にもなんらかのパラメータが返ります。
- Twitterのエラーはどこに書いてるか忘れた
- ログインフローを手動で構築する - Facebookログイン - ドキュメンテーション - Facebook for Developers
- Using OAuth 2.0 for Web Server Applications | Google Identity Platform
- RFC6749 - 4.1. Authorization Code Grant - 4.1.2. Authorization Response
これらを適切に処理して、ハンドリングを行いましょう。
というか、"成功しなかった場合" で良いのでハンドリングしましょう。
- しれっとログイン画面やID連携のサービス選択画面に戻るのが正解
- キャンセルされました ぐらいは表示してもよい
- ステータスコードとしては50x系でも40x系でもなく200でおk
ぐらいを気をつけると良さそうです。
まとめ
- サービスによって、ID連携要求時にキャンセルできるところがある
- その場合、ユーザーがキャンセルしましたよみたいなエラーパラメータがついて戻ってくる
- こんな実装はよくないという例を示した
- これぐらいで良いのではという例を示した
ということで、ID連携のキャンセル時の挙動もちゃんとハンドリングしましょう
ではまた!
Discussion