Rails トークンベース認証 - izudon/izudon.github.io GitHub Wiki

ログイン・ログアウト

以下の仕様が良いのではないかと感覚的に思った。

  • ログイン・ログアウト処理が返すもの(レスポンス)
    • ログインはトークンだけを返す。
    • ログアウトは、トークンがあっている(ログイン中のユーザである)場合、
      ログアウト処理(トークンの削除)の後、ユーザ ID だけを返す。
    • トークンがあっていない(ログイン中のユーザではない/偽トークン)の場合、
      適当な何かを返す(成功扱いと一応する)。
  • タイムアウト
    • アクセスタイムアウト
      90分程度以上アクセスのなかったトークンは無効とする(エラーを返す)。
      updated_at を参照する)
      • このとき、トークン(レコード)は削除してしまって良い。
    • トークンタイムアウト
      6時間程度以前に発行されたトークンであれば、たとえ90分以内に、
      最終アクセスが上がっていたとしても、無効としてエラーを返す。
      created_at を参照する)
      (同じトークンが延々引き伸ばされて利用されてしまうのを防ぐため)。
      • このとき、トークン(レコード)は削除してしまって良い。
  • マルチデバイス(マルチログイン)対応
    • 30秒間にログインは5回までとし、
      30秒間で6回目以降のログイン要求(トークン要求)は弾く(エラーとする)。
      • ログイン要求時点から過去30秒間に発行された、等がユーザに対する、
        トークンの数(レコード数)を確認する(created_at の参照)。
        5件以上であれば弾く(エラーとする)。
      • sshd の仕様に着想を得た。
    • トークンは1ユーザあたり10個を上限とし、11個目のログイン要求があれば、
      新規トークン発行にあたり、最も使われていないトークンを削除する。
      • トークンでアクセスされた際 updated_at を更新するようにしておく。
      • updated_at が最も古いトークンを削除する。
  • トークンの暗号化
    • DBバックアップなどの際にオペレーション作業者が内容を盗み見て、
      ユーザになりすましたりするのを防ぐため、トークンはハッシュ値だけを保存する。
    • OpenSSL::HMAC を使う。
    • 副作用として、一度発行したトークンを再度ユーザに送ることができなくなる。
      ログインボタンが連打されたら、連打された数だけトークンを発行するしかなくなる。
      悪用を防ぐため、上記の「30秒に5回まで」「1ユーザあたり10個まで」の、
      制約を設けている。

資料