はじめに
現在、個人開発をしておりその中で認証機能を組み込もうと考え、JWT認証を入れてみようとなったので調べたことをアウトプットしたいと思います。
これから、JWTについて知りたい方の参考になれば幸いです。
JWTとは
JWT(ジョット)とは、Json Web Tokenの略です。
ユーザー認証や、情報を安全にやり取りするために、使用されるトークンで、Json形式のデータをエンコードしたものです。
JWTの構成
JWTは、ドット(.)で区切られた3つの要素で構成されます。
ヘッダー
使用する署名アルゴリズムやトークンタイプを指定します。
{
"alg": "HS256",
"typ": "JWT"
}
ペイロード
ペイロードは、ユーザー情報や、任意の情報を追加することができます。
また、subやexpなどをクレームと呼びます。
{
"sub": "1234567890",
"name": "Yamada Taro",
"exp": 1610003600
}
署名
署名は、ヘッダーとペイロードが改ざんをされていないか、発行者が正当か検証するために使用されます。
エンコードされた、ヘッダーとペイロードをドット(.)で繋ぎ、指定した暗号鍵、アルゴリズムで署名します。
その署名をさらに、BASE64URLエンコードします。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
JWTはどのように使用するのか
今回は共通鍵暗号方式のため、サーバー(Railsアプリケーション)がJWTの発行と検証を行います。
サーバーのみが秘密鍵を保持しています。
JWT発行
-
クライアントから、emailやユーザー名、パスワードなどの認証情報を入力しユーザーはログインします
-
ログインに成功すると、サーバーが、ユーザーIDなどの情報を含むペイロードを作成し、秘密鍵で署名をして、JWTの発行を行います
-
発行したJWTを、サーバーはクライアントへ渡します
JWT検証
- クライアントは、次回以降のリクエスト時、HTTPヘッダー(Authorization: Bearer )にJ
WTを含めて送信します。 - サーバーは受け取ったJWTを、所持している秘密鍵を使用して検証し、トークンが有効期限内か改ざんがないことを確認します
- 検証に成功した場合リクエストが処理されます
RailsでJWTを使用する方法
Gemでインストール
Gemfileにjwtを追記し、bundle installします。
gem "jwt"
ペイロードの作成
任意の情報を埋め込み、ペイロードを作成します。
誰のIDか、トークンの有効期限をここで設定します。
payload = { user_id: user.id, exp: 24.hours.from_now.to_i }
暗号鍵の設定
署名時に使用する鍵を設定します。
外部に漏れると危険なため、Railsのシークレットキーを使用します。
secret = Rails.application.credentials.secret_key_base
トークン発行
JWT.encodeを使用してトークンを発行します
token = JWT.encode(payload, secret)
デコード
トークンの確認にはJWT.decodeメソッドを使用します
decode_token = JWT.decode(token, secret)
最後に
JWTの仕組みについて、まとめました。
JWTを利用することで、サーバー側でセッション状態をもたないステートレスな、認証システムを構築できます。
実際の、アプリケーションではクライアント側でどのように保存するかなど、セキュリティ面でも考えなければいけないこともあるので、また記事にしたいと思います。