今さら聞けない認証方法まとめ

# 今さら聞けない認証方法まとめ

安全なWebアプリケーションの開発には不正アクセスの脅威からアカウントを守る必要があります。

その為に必要なのが、**誰であるかを実証する「認証」、その権限を持つかを実証する「認可」**　です。

```
認証： 「あなたは誰ですか？」 を確認
認可： 「あなたには、リソースにアクセスする権限がありますか？」 を確認
```

## ユーザー認証、認可のフロー

シンプルなWebアプリケーションのユーザー認証、認可のフロー

```
1. ID/パスワード入力
2. バックエンド認証システムに対してIDに紐づくパスワードが正しいか照合する　-> 認証
3. 照合結果（ユーザーに付与されたサービス提供範囲）をWebシステムに返却する -> 認可
4. 確認結果をもとにユーザーにサービス提供する
```

２の認証フロー

```
1. クライアントからサーバーに認証情報を送る
2. サーバー上で認証情報を検証する
3. 認証情報が正しければ、クライアントにアクセストークンを送る（+必要に応じてセッションに記録する）
```

## 認証方法まとめ

### その１：　ベーシック認証（基本認証）
Basic認証（ベーシック認証）とは、HTTPで定義される認証方式の一つです。

IDとパスワードをBase64でエンコードしてHTTPヘッダのAuthorizationフィールドに記載しサーバーに送信します。

Basic認証は実装が容易で、ほぼ全てのWebサーバおよびブラウザで対応している事もあり、簡易的な認証として広く使われています。

しかし、IDとパスワードをBase64でエンコードして送信する為、盗聴すれば簡単にIDとパスワードが分かってしまので注意が必要です。

■　Basic認証のパップアップ画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286094/bed05617-cacf-6645-6ec0-03a5d952dd4f.png)

■　Basic認証フロー図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286094/cb8dfdef-27ec-a9b0-eebd-24cc710b6155.png)
画像参照：https://gigazine.net/news/20201227-web-authentication-methods-compared/


### その2：　ダイジェスト認証
ダイジェスト認証はベーシック認証の改良版みたいなイメージです。

Basic認証では「ユーザーID」と「パスワード」を平文で送信します。
その結果、脆弱性に繋がります。

一方、Digest認証はサーバが生成したランダムの文字列をパスワードに付与し、IDとパスワードをMD5でハッシュ化し送信します。そのため盗聴されてもパスワードの解析が困難となります。

サーバ側では登録済みの情報から同じようにハッシュ値を算出し、クライアントから受信したハッシュ値に一致すれば認証成功となります。

■　ダイジェスト認証フロー図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286094/b14dd456-f49c-1c47-e736-2a8e71c3e9a3.png)
画像参照：https://gigazine.net/news/20201227-web-authentication-methods-compared/

### その3：　セッションベースの認証
通信のたびにユーザ名とパスワードを送るのはハッキングを受ける確率も増え、毎回認証のオーバーヘッッドも大きくなります。

そこでセッションを使うセッションベースの認証が開発されました。

はじめにサーバはクライアントにランダムな値のセッションIDを送信します。(セッションIDはクッキーに保存)

サーバはセッションIDと紐付ける事でクライアントの状態を保持できるため認証が成功すれば、その後はセッションIDの確認だけで認証が不要になります。

ただ、セッションベースの認証ではセッションIDが漏洩するとサーバーの情報が盗まれるので注意が必要です。

セッションベースの認証では認証が必要なくてもCookieをリクエスト毎に送信する必要があるため、[クロスサイトフォージェリ](https://qiita.com/Marusoccer/items/cdc6124570ed1f5733bd#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%82%B8%E3%83%A5%E3%82%A8%E3%83%AA)にあうリスクが高い点です。

■　セッションベース認証フロー図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286094/698b04bb-070b-34bd-c9f1-556b5738d4cd.png)
画像参照：https://gigazine.net/news/20201227-web-authentication-methods-compared/



### その4：　トークン（アクセストークン）ベースの認証
トークンベース認証は、先ほどのセッションベース認証で用いていたCookieの代わりに、トークンを利用します。

トークンで一般的に使用されるのがJWTです。

JWTについては[こちらの記事](https://qiita.com/Marusoccer/items/c8632134f08a935ccfc9)が参考になります。

■　JWT構成

```
ヘッダー: 署名の検証に必要な情報
ペイロード: やり取りに必要な情報。ユーザー情報など
署名:検証する内容
```

トークンの受け渡し方法としては特定の条件を除いてAuthorizationヘッダーで行えばよいです。

```
Authorization: Bearer <アクセストークン>
```

クライアントはサーバーに通信する際に上記で述べたAuthorizationヘッダーにに乗せて認証します。

つまり、クライアント側でアクセストークンを保持しておかなければなりません。

クライアントでの格納先として下記の４パターンが多いです。

| 保存先 | 概要 |
| :--- | :---: |
| OS標準のストレージ | iOSのKeyChain、AndroidのKeyStore |
| メモリ | JavaScriptの変数など |
| Cookie | WebブラウザのCookie |
| localStorage | Web Storage APIのlocalStorage |

■　セッションベース認証フロー図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286094/7e4aa39d-f506-a986-9261-b13b2cbb92f2.png)
画像参照：https://gigazine.net/news/20201227-web-authentication-methods-compared/


### その5：　ＯAuth／OAuth2またはOpenID
OAuth / OAuth2とOpenIDは、Facebook、Twitter、Googleなどのソーシャルネットワーキングサービスからの既存の情報を使用して、シングルサインオン（SSO）の形式であるソーシャルログインを実現する手段です。

こちらの記事が参考になります
https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be

■ SAMLとOAuthの違い

> OAuthはGoogleやTwitter等のSNSの認証を目的として開発されたもので比較的簡易的なプロトコルです。一方でSAMLは、非常に複雑な権限管理を行うことができます。
このような違いにより、OAuthおよび、拡張したOpenID ConnectはFacebookやTwitterなどのSNSの認証で使用されることが多いです。また、SAMLは、Active Directoryの機能の一つであるADFS（Active Directory Fereration Service）やOktaなどIDPサービスで主に用いられています。

参照：　[SAMLとOAuthの違い](https://i.moneyforward.com/resources/saml_sso)

## まとめ

|認証方法 | 実装容易 | セキュリティレベル |
| :--- | :---: | :---: |
| ベーシック認証 | ◎ | ✖︎ |
| ダイジェスト認証 | ◎ | ✖︎ |
| セッションベース認証 | ○ | △ |
| トークン（アクセストークン）ベース認証 | ○ | △ |
| ＯAuth／OAuth2またはOpenID | △ | ◎ |

上記のように認証方法は数パターン存在しますが。

個人的にはベンダーロックインを気にしないのであれば、実装はFirebase Authenticationを利用することをお勧めします。

Firebase Authentication は他の Firebase サービスと緊密に統合されており、OAuth 2.0 や OpenID Connectの実装をノーコード（ローコード）で実装が可能です。

■ [Firebase Authentication](https://firebase.google.com/docs/auth?hl=ja#:~:text=C%2B%2B%20Unity-,%E4%BB%95%E7%B5%84%E3%81%BF,Authentication%20SDK%20%E3%81%AB%E6%B8%A1%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)説明動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/8sGY55yxicA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## その他
参考：[Software Design 2020年11月号](https://gihyo.jp/magazine/SD/archive/2020/202011)


https://applis.io/posts/how-to-authenticate-user


https://arakan-pgm-ai.hatenablog.com/entry/2021/08/23/000000

https://qiita.com/YukiMiyatake/items/4c2162f85fe3c9c203a7