0時に寝て4時ぐらいに起きてだらだらして7時半に起きた。やっぱりあまり眠れない。

ステートレスな認証という概念

次の開発フェーズが始まっていて、ちょっと時間が経ってしまったが、前開発フェーズのお披露目的な製品紹介をお手伝い先の全社向けに行った。主には直近の開発フェーズで追加した機能などを紹介した。その過程で新たに認証の仕組みを追加して jwt で認証するといった話しをしたところ、それはステートレスなのかどうかといった質問が出た。セキュリティを考慮して、アーキテクチャ的にフロントエンドの認証と api サーバーの認証は分けて実装しているのと、そのために仕組みも複雑になっているのだけど、ステートレスという言葉が指す意図を私がよくわかっていなくて、うまく説明できなかった。説明を終えた後にアーキテクチャのイメージ図と一緒に補足をしながらやり取りして次の記事を教えてもらった。

jwt は暗号化の技術で認証する仕組みなので有効期限が切れるまでは有効なアクセストークンとなる。そのため、jwt のみだとログアウトという概念はないため、そこをどうしているのか?という質問だった。フロントエンド/api サーバーともに session をオンメモリで保持して、ログインしたユーザーを管理しているため、ログアウトしたら session からレコードを削除することで有効な jwt のアクセストークンが来ても認証エラーにしてしまうことでステートをもった認証方式を実現している。とくまる先生が次のように説明しているところ。

「セッションIDをJWTに内包する」 という考え方です。

うちはこれをセッション ID ではなくユーザー名でやっている。とくに難しいことをやっているわけではなく、普通に実装したらそんな感じかな?と考えていたが、jwt = ステートレス認証だと思い込んでいる人たちがいるから ストートレスな認証 というキーワードが出てきたんだなと理解できた。最近のトレンドとしてはログアウトで jwt のアクセストークンを無効にできないと脆弱性と指摘される可能性がありそうとも書いてある。

ログアウト時にJWTを無効化できない実装は今後脆弱性診断で「OWASP Top 10 2021違反」と指摘されるようになりそう(今も個別にされてるかもしれないけど)

私はアーキテクチャ的にブラウザに api サーバーのアクセストークンをみせないというところに注力して認証機能の開発をサポートしていた。それ自体も間違っていないとは思うけど、今回の質問はその工夫とは異なるところの質問だった。認証は難しい。