の認証は、方式ごとに「何を」「どこに」載せるかが違います。ドキュメントの書き方も統一されていないので、まず型を見分けるのが早道です。この回では4つの型と、それぞれの注意点を扱います。
型1: API キー ── 一番単純で、一番漏れやすい
発行された文字列を、そのまま添えるだけの方式です。に載せるタイプと、 に載せるタイプがあります。どちらで送るかは配信元が決めているので、選べないことも多いです。
クエリ文字列に載せる方式には、無視できない弱点があります。URL はアクセスログやブラウザの履歴、リファラに残るので、鍵が意図せず広がります。選べるならヘッダ方式を選んでください。
import osimport requests
API_KEY = os.environ["EXAMPLE_API_KEY"] # 無ければここで落ちるのが正しい
resp = requests.get( "https://api.example.com/v1/items", headers={ "X-API-Key": API_KEY, "User-Agent": "hukuhuku-data-fetch/1.0 (+https://hukuhuku.co.jp)", }, timeout=(5, 30),)resp.raise_for_status()`get()` は鍵が無いと `None` を返し、認証なしで叩きに行って 401 になります。原因が「鍵が無い」ことだと気づくまで遠回りします。無ければその場で落ちるほうが早く直ります。
型2: Bearer トークン
`Authorization: Bearer <トークン>` の形で送ります。API キーとの違いは、トークンに有効期限があることが多い点です。取得処理が長時間走る場合、途中で期限が切れて 401 になります。
期限切れを 401 として受け取ったら、トークンを取り直して再試行する、という流れを組み込みます。ここは EP.03 で扱った「やり直してよい失敗」の例外で、401 でも1回だけはやり直す価値があるケースです。
型3: OAuth2 ── 誰の権限で読むのか
は、利用者本人の代わりにデータへ触るための仕組みです。取得処理で使う場合、大きく2つの流れに分かれます。
| 流れ | 誰の権限か | ブラウザ操作 | 向く用途 |
|---|---|---|---|
| クライアント認証情報 | アプリ自身 | 不要 | 自動化・定期取得 |
| 認可コード | 利用者本人 | 初回のみ必要 | 利用者のデータを読む |
定期実行したいなら、ブラウザ操作が要らない前者を選べるかどうかが分かれ目です。後者しか無い場合は、初回だけ人手で認可を通し、以降は更新用トークンで繋ぎます。更新用トークンにも期限や失効条件があるので、切れたときに気づける通知を用意しておく必要があります。
を使う方式も、実質は前者の一種です。鍵ファイルを持たせて、そのアカウントの権限で読みます。人のアカウントに紐づかないので、担当者が退職してもデータ取得が止まらないという利点があります。権限は必要な範囲だけに絞って与えてください。
後者を使わざるを得ない場合、鍵になるのは の寿命です。これが切れると取得が止まりますが、止まったことに気づく仕組みが無いと、数日ぶんのデータが欠けてから発覚します。取得件数がゼロの日を検知して通知する、くらいの単純な監視で足ります。
import requests
def get_with_reauth(url: str, get_token, max_reauth: int = 1, **kwargs): """401 を受けたらトークンを取り直して 1 回だけやり直す。 それでも 401 なら、期限切れではなく権限不足なので諦める。""" token = get_token() for attempt in range(max_reauth + 1): headers = {**kwargs.pop("headers", {}), "Authorization": f"Bearer {token}"} resp = requests.get(url, headers=headers, timeout=(5, 30), **kwargs) if resp.status_code != 401 or attempt == max_reauth: resp.raise_for_status() return resp token = get_token(force_refresh=True) raise RuntimeError("到達しない")型4: 署名 ── 送る内容そのものに鍵をかける
鍵をそのまま送らず、要求の内容から計算した署名を送る方式です。クラウドの API や暗号資産取引所で使われます。署名には時刻を含めるのが普通で、これによって同じ要求の使い回しを防ぎます。
自前で実装すると、署名対象の文字列の組み立て方(パラメータの並び順、エンコードの仕方)でつまずきます。公式のがあるならそれを使うのが確実です。
鍵をコードに書かないための最低限
どの型であっても、鍵をソースコードに直接書かないという点は共通です。書いてしまうと、リポジトリを共有した相手全員に渡り、履歴からも消えません。
- 環境変数から読む — 最も手軽。`.env` を使うなら `.gitignore` に入れる
- 鍵の管理サービスを使う — 共有と失効の手間が減る。チームで運用するなら
- プレースホルダを実値らしく書かない — サンプルは `YOUR_API_KEY` のように、明らかに仮の値だと分かる形に
履歴に残っているので、その鍵は失効させて作り直すのが唯一の対処です。「消したから大丈夫」にはなりません。公開リポジトリなら、コミットから数分で自動収集される前提で動いてください。
認証情報は、動いている間は誰も触らないぶん、担当が変わったときに真っ先に分からなくなる部分です。どの鍵がどのサービスのもので、誰が発行し、いつ切れるのか。この対応表が無いと、切れた瞬間に手が出せません。認証まわりの設定を他人へ引き継ぐ話は エンジニアの引き継ぎ術 でも扱っています。次回は、取得したデータをどこに、どの形で置くかを扱います。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。