Go言語によるBearer認証の実装サンプル

Go言語で実現するBearerトークン認証

モダンなWeb API開発において、セキュリティを確保するための認証方式として「Bearerトークン(主にJWTなど)」は事実上の標準となっています。 Go言語の標準ライブラリ net/http を用いて、この認証ヘッダーを正しく、かつ安全に実装する方法を詳しく解説します。


1. 実装サンプルコード

以下のコードは、JSONデータをPOSTしつつ、AuthorizationヘッダーにBearerトークンを付与する完結したサンプルです。 エラーハンドリングやタイムアウト設定など、実務で必須となる要素を盛り込んでいます。


package main

import (
	"bytes"
	"fmt"
	"io"
	"net/http"
	"time"
)

func main() {
	// 接続先URLと認証トークンの定義
	const (
		apiURL      = "https://example.com/api/v1/resource"
		bearerToken = "your_secret_access_token"
	)

	// 送信するペイロード(JSON)の構築
	payload := []byte(`{"name": "Gopher", "role": "Developer"}`)

	// 1. リクエストオブジェクトの生成
	// http.Post() 等の簡易メソッドではヘッダーの個別設定ができないため、NewRequestを使用します
	req, err := http.NewRequest(http.MethodPost, apiURL, bytes.NewBuffer(payload))
	if err != nil {
		fmt.Printf("リクエストの作成に失敗しました: %v\n", err)
		return
	}

	// 2. 必須ヘッダーの設定
	// Bearerの後には必ず半角スペースが必要です
	req.Header.Set("Authorization", "Bearer "+bearerToken)
	req.Header.Set("Content-Type", "application/json")

	// 3. HTTPクライアントの実行
	// http.DefaultClient はタイムアウトが設定されていないため、独自のClient定義を強く推奨します
	client := &http.Client{
		Timeout: 10 * time.Second,
	}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("通信エラーが発生しました: %v\n", err)
		return
	}
	// リソースリークを防ぐため、必ずCloseを呼び出す
	defer resp.Body.Close()

	// 4. 結果の読み取りと判定
	body, _ := io.ReadAll(resp.Body)
	if resp.StatusCode == http.StatusOK {
		fmt.Printf("成功: %s\n", string(body))
	} else {
		fmt.Printf("サーバーエラー: %d - %s\n", resp.StatusCode, string(body))
	}
}
    

2. 実装上の重要なTips

なぜ http.NewRequest を使うのか?

http.Gethttp.Post は内部でデフォルトのクライアントを使用しており、独自のヘッダーを追加する機能がありません。 認証が必要なAPIを叩く場合は、http.NewRequest を使用してリクエストインスタンスを生成し、Header.Set で個別に制御するのが正しいアプローチです。

Bearerスキームの書式に注意

Authorizationヘッダーの値は Bearer <token> という形式で指定する必要があります。 この Bearer とトークンの間の半角スペースを忘れると、サーバー側で正しくパースされず、401 Unauthorizedエラーの原因となります。

プロダクション環境での注意点

  • タイムアウト: ネットワークの遅延やサーバーの無応答に備え、必ず http.Client にタイムアウトを設定してください。
  • トークンの秘匿: トークンをコード内にハードコードせず、環境変数(os.Getenv)やシークレット管理サービスから取得するようにしましょう。