はじめに
先日、社内で Web セキュリティ について、話す機会がありました。
普段、Web系の仕事しているので触れる機会が多いですが、知らない事も沢山ありました。
そこで、基礎的な事から学びなおします。
まずは、基本の「HTTP」からです。
ブラウザ・サーバー・API・認証・キャッシュなど、HTTPを中心としたさまざまな仕組みを理解することで、原因調査や設計力が大きく向上します。
せっかくなので、次回のLT会ようにまとめたいと思います。
HTTPはネットワークのどこで動いているのか
HTTPはOSI参照モデルやTCP/IPモデルの中ではアプリケーション層に位置するプロトコルです。
ブラウザ → HTTP → TCP → IP → Ethernet
HTTPはTCPの上で動作しています。
そのため、下記の各エラーはそれぞれ発生する場所が異なります。
この違いを理解すると、通信エラーの切り分けができるようになります。
- HTTPエラー
- TCP接続エラー
- DNSエラー
URLを入力してから画面が表示されるまで
ブラウザでURLを入力すると、実は多くの処理が行われています。
- URL解析
- DNS問い合わせ
- IPアドレス取得
- TCP接続
- TLS(HTTPS)接続
- HTTP Request送信
- サーバー処理
- HTTP Response受信
- HTML解析
- CSS取得
- JavaScript取得
- API通信
- 画面表示
Chrome DevTools の Network タブを見ると、下記の項目などの時間を確認できます。
「画面表示が遅い」という問題も、どこに時間がかかっているか分析できるようになります。
- DNS Lookup
- Initial Connection
- SSL
- Request
- Response
HTTP Requestをもっと詳しく見る
HTTPリクエストは次のような構造になっています。
POST /users HTTP/1.1
Host: example.com
User-Agent: Chrome
Accept: application/json
Authorization: Bearer xxxxxx
Content-Type: application/json
Content-Length: 42
{
"name": "Taro"
}
構成は以下の4つです。
- Request Line
- Header
- 空行
- Body
Headerには通信に必要な情報が数多く含まれています。
HTTP Responseをもっと詳しく見る
レスポンスも同じような構造です。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache
ETag: "abc123"
{
"id":1,
"name":"Taro"
}
代表的なレスポンスヘッダー
- Content-Type
- Content-Length
- Server
- Date
- Cache-Control
- Set-Cookie
- ETag
これらを理解するとブラウザの動作も理解できます。
HTTPメソッドをもっと知る
一般的によく使われるのは以下です。
| メソッド | 用途 |
|---|---|
| GET | 取得 |
| POST | 作成 |
| PUT | 更新 |
| PATCH | 一部更新 |
| DELETE | 削除 |
しかし、HTTPには他にもあります。
| メソッド | 用途 |
|---|---|
| HEAD | Headerのみ取得 |
| OPTIONS | 利用可能なメソッド確認 |
| TRACE | 通信確認 |
| CONNECT | トンネル接続 |
特に OPTIONS はCORSで非常によく利用されます。
ステータスコードを深く理解する
HTTPステータスコードは5つのグループに分かれています。
1xx
情報通知
| コード | 意味 |
|---|---|
| 100 | Continue |
実務ではあまり見ません。
2xx
成功
| コード | 意味 |
|---|---|
| 200 | 成功 |
| 201 | 作成成功 |
| 202 | 受付完了 |
| 204 | 成功(Bodyなし) |
POSTで新規作成した場合は201を返す設計が一般的です。
3xx
リダイレクト
| コード | 意味 |
|---|---|
| 301 | 恒久的移動 |
| 302 | 一時的移動 |
| 303 | 別URIへ |
| 304 | Not Modified |
| 307 | メソッド維持 |
| 308 | 恒久的+メソッド維持 |
SEOやURL変更時にも利用されます。
4xx
クライアントエラー
新人が最も混乱しやすい部分です。
- ログインしていない → 401 Unauthorized
- ログイン済み → 権限がない → 403 Forbidden
代表例
| コード | 意味 |
|---|---|
| 400 | 入力不正 |
| 401 | 認証エラー |
| 403 | 権限不足 |
| 404 | 存在しない |
| 405 | HTTPメソッド違い |
| 409 | 競合 |
| 415 | Content-Type不一致 |
| 422 | 入力チェックエラー |
| 429 | アクセス制限 |
5xx
サーバーエラー
| コード | 意味 |
|---|---|
| 500 | 内部エラー |
| 502 | Bad Gateway |
| 503 | サービス停止 |
| 504 | Gateway Timeout |
AWSのALBやCloudFrontでもよく見かけます。
HTTP Header完全ガイド
Headerは通信の追加情報です。
代表的なものを覚えておくと実務で非常に役立ちます。
| Header | 用途 |
|---|---|
| Host | アクセス先 |
| Authorization | 認証 |
| Accept | 受け取りたいデータ |
| Content-Type | 送信データ |
| Content-Length | Bodyサイズ |
| Cookie | Cookie送信 |
| Origin | CORS判定 |
| Referer | 遷移元 |
| User-Agent | ブラウザ情報 |
| Cache-Control | キャッシュ |
| ETag | キャッシュ識別 |
| If-None-Match | 304判定 |
※HTTPコード:304「ファイルは更新されていません。ブラウザのキャッシュをそのまま使ってください。」
Bodyの種類
BodyはJSONだけではありません。
| Content-Type | 用途 |
|---|---|
| application/json | REST API |
| multipart/form-data | ファイルアップロード |
| application/x-www-form-urlencoded | HTMLフォーム |
| text/plain | テキスト |
| application/xml | XML |
Spring BootではJSONを扱うことが最も多いですが、ファイルアップロードではmultipart/form-dataが利用されます。
Cookieを理解する
Cookieはブラウザに保存されるデータです。
Server → Set-Cookie → Browser → Cookie保存 → 次回アクセス → Cookie送信
最近はセキュリティのために次の属性も重要です。
- HttpOnly
- Secure
- SameSite
Sessionを理解する
Sessionはサーバー側でユーザー情報を保持します。
Browser → Cookie(SessionID) → Server → Session情報
Sessionの保存先として、下記などがあります
- メモリ
- Redis
- データベース
JWT認証
最近のSPAではこちらが主流です。
JWT認証とは、ログイン時に発行されたトークン(JWT)をHTTPヘッダーに付けて送信し、ユーザー本人であることを証明する認証方式です。
ログイン → JWT発行 → Authorization: Bearer xxxxxx → APIアクセス
Cookie認証との違いも理解しておくとよいでしょう。
HTTPSとTLS
HTTPSはHTTPを暗号化した通信です。
HTTP → 平文 → 盗聴可能
HTTPS → TLS暗号化 → 盗聴されにくい
さらに理解を深めるなら、下記も一緒に学ぶ必要があります。
- サーバー証明書
- 公開鍵暗号
- 共通鍵暗号
- TLSハンドシェイク
CORS
SPA開発では避けて通れない知識です。
CORS(Cross-Origin Resource Sharing)とは、異なるオリジン(ドメイン・ポート・プロトコル)間でのHTTP通信を、安全に許可・制御する仕組みです。
Vue.js
localhost:5173
↓
Spring Boot
localhost:8080
↓
Originが違う
↓
ブラウザがブロック
このときブラウザは事前に
OPTIONS
を送信します。
これを Preflight Request と呼びます。
Preflight Requestとは、実際のHTTPリクエストを送信する前に、ブラウザがサーバーへ通信を許可してよいか確認するために送る事前リクエスト(OPTIONSリクエスト)です。
キャッシュ
キャッシュを理解するとWebアプリの高速化につながります。
Browser → キャッシュ確認 → 304 Not Modified → 再利用
覚えておきたいHeader
- Cache-Control
- ETag
- Last-Modified
- If-None-Match
CloudFrontなどのCDNでも重要な知識になります。
HTTP/1.1・HTTP/2・HTTP/3
現在利用されているHTTPにも世代があります。
| 項目 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 通信方式 | TCP | TCP | QUIC(UDP) |
| 多重通信 | × | ○ | ○ |
| ヘッダー圧縮 | なし | HPACK | QPACK |
| 速度 | 普通 | 高速 | さらに高速 |
Chrome DevToolsでは「Protocol」列で h2 や h3 を確認できます。
※TCPとQUIC(UDP)の違いとして、TCPは信頼性を重視した通信プロトコルで、QUIC(UDP)はUDPをベースに高速な接続確立や通信を実現したプロトコルです。
※HPACKとQPACKの違いとして、HPACKはHTTP/2で使用されるヘッダー圧縮方式、QPACKはHTTP/3(QUIC)向けに改良され、通信の待ち時間を減らせるヘッダー圧縮方式です。
REST API設計
HTTPメソッドを理解するとREST APIの設計もしやすくなります。
GET /users
一覧取得
GET /users/1
詳細取得
POST /users
新規登録
PATCH /users/1
更新
DELETE /users/1
削除
RESTでは
- URLは名詞にする
- HTTPメソッドで操作を表現する
という考え方が基本です。
※POST /users/create などは絶対にやめましょう
Chrome DevToolsでHTTPを確認する
知識だけでなく、実際にブラウザで確認する習慣を付けましょう。
Networkタブでは以下を確認できます。
- Request URL
- Request Method
- Status Code
- Request Headers
- Response Headers
- Query Parameters
- Request Payload
- Response Body
- Cookies
- Timing
- Protocol
API開発では「まずNetworkタブを見る」ことが問題解決の第一歩になります。
今後さらに学びたいテーマ
HTTPを理解したら、次のテーマもおすすめです。
- DNSの仕組み
- TCP/IP通信
- TLSハンドシェイク
- WebSocket
- SSE(Server-Sent Events)
- GraphQL
- gRPC
- OAuth2
- OpenID Connect
- CDN(CloudFront)
- API Gateway
- ロードバランサ(ALB)
- リバースプロキシ(Nginx)
- ブラウザキャッシュ
- Service Worker
- HTTPキャッシュ戦略
これらを学ぶことで、Webアプリケーション全体の通信をより深く理解できるようになります。
おわりに
改めて見てみると「HTTP/2・HTTP/3の違い」など、分からない事が出てきました。
最近はAIでパッと答えっぽいモノが出てしまいますが、”見つけるのが速い=忘れるのも早い”ので、このQiita記事で「頭のアウトプット」をして、しっかりとした基礎知識を身に着けていきたいと思いました。
参考(感謝)
- AIに聞きながら
