Laravel(APIモード)でfetch APIを使ってフロントとの通信を行う際に、認証を要するアクションでAuthorization: Bearer ${token}を使って認証を行う機会があり、そもそもBearer認証とは?という疑問から今回の記事を投稿するに至りました!
参考:【入門】認証方式とサーバーの設定をわかりやすく解説
参考:トークンを利用した認証・認可 API を実装するとき Authorization: Bearer ヘッダを使っていいのか調べた
参考:一番分かりやすい OAuth の説明
認証の種類について
たくさんあります。
- セッション
- リクエストにトークンを含める
- ヘッダにトークンを含める
- Authorizationヘッダでの認証
- JWT認証
今回はwebサービスにおいてよく使われるタイトルの認証方法についてまとめたいと思います。
Bearer(アクセストークン認証)
ログイン・パスワードでユーザー認証を行った際に、認可サーバーから発行されるアクセストークンを使って、APIのリクエスト時にAuthorizationヘッダにアクセストークンを含めて送信します。
Bearer認証の流れ
- クライアントがログイン時にサーバーはアクセストークンを発行
- 発行されたトークンをクライアントのブラウザ内のsessionStrageかlocalStrageに保存
- ページへのアクセス時にAuthorizationヘッダにトークンセットし、サーバーにRequest送信(下記コード参照)
- サーバーはトークンを確認し、有効ならリクエストされたページをレスポンス
認証に失敗するとサーバーは401 Unauthorizedを送信する。
トークンの形式はtoken68の形式で指定することが定められています。
// SessionStrageからトークンを取得し、変数に代入
const token = sessionStorage.getItem('access_token');
fetch("/api", {
method: 'GET',
// トークンを送信
headers: {
Authorization: `Bearer ${token}`
}
})
.then.......
発行したトークンはクライアント側がlocalStrageかsessionStrage、サーバー側はDBにそれぞれ保存します。
Basic認証
AuthorizationヘッダにIDとPASSをセットし、Base64でエンコードした上で送信する方法。認証に成功すると認証情報がキャッシュに保存されます。
Basic認証の流れ
- クライアントがIDとPASSを入力
- Base64でエンコードしてサーバーに送信
- サーバーはデータをBase64でデコードして認証を行う
- 認証が成功するとサーバーからクライアントに要求されたページを送信
- ブラウザは認証状態をキャッシュし、キャッシュクリアされるまで認証状態が継続される
Base64はデコードすれば簡単にIDとPASSが見れるため、脆弱性を含んでいます。しかし、この問題はHTTPS通信(SSL/TLSを用いてデータを暗号化)でカバーすることが可能です。
Basic認証単体ではログアウト機能の実装ができません。後述するForm認証(後述)によって、ログアウト機能を実装することが可能です。
Digest認証
Basic認証の脆弱性を改善した認証方式だが、HTTP通信に有効な方法であるため、HTTPS通信が主流の現代においてはBasic認証の方が利用されます。
Digest認証の流れ
- サーバーがランダムな文字列を生成し、クライアントに送信
- クライアントがIDとPASSを入力
- ランダムな文字列とPASSをAuthorizationヘッダにセットし送信
- サーバーがデータが正しいか確認し、認証を行う
Form認証
前提として、Form認証はHTTPの仕様にはない認証方式です。つまり、アプリケーション側で実装する方法です。
認証に成功すると、ブラウザ内のSessionにセッションIDを保存することでログイン状態を管理します。
Basic認証との違いは、ログアウト機能、シングルサインオン機能が実装できる点です。
Form認証の流れ
- クライアントがHTMLフォーム画面にIDとPASSを入力し、サーバーへ送信(平文での送信のため、HTTPS通信が必須)
- サーバーは内容を検証後、正しければセッション管理を開始しブラウザにセッションIDを返却
- クライアントはセッションIDが有効な期間ログイン状態を維持することが可能