Go言語でBasic認証付きHTTPサーバーを実装する

Go言語でHTTPサーバーを構築する際、リクエストにBasic認証を適用したい場合がある。本稿では、モジュール化されたプロジェクト構成のもと、カスタムパッケージを用いてBasic認証を実装する方法を紹介する。

プロジェクトのセットアップ

まず、作業ディレクトリを作成し、Goモジュールを初期化する:

$ mkdir auth_http && cd auth_http
$ go mod init my_auth

これにより go.mod ファイルが生成され、モジュール名が my_auth となる。

ディレクトリ構成

以下の構造でファイルを配置する:

.
├── go.mod
├── server.go
└── auth
    └── validator.go

コード実装

メインサーバーのロジックを server.go に記述する:

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"

	"my_auth/auth"
)

type PayloadHandler struct{}

func (h *PayloadHandler) Handle(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	user, pass, ok := r.BasicAuth()
	if !ok || !auth.Validate(user, pass) {
		w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
		http.Error(w, "401 Unauthorized", http.StatusUnauthorized)
		return
	}

	var data map[string]interface{}
	if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
		http.Error(w, "Invalid JSON payload", http.StatusBadRequest)
		return
	}

	for k, v := range data {
		fmt.Printf("%s: %v\n", k, v)
	}

	w.WriteHeader(http.StatusOK)
	w.Write([]byte("Payload processed successfully\n"))
}

func main() {
	port := flag.String("p", "8080", "ポート番号")
	flag.Parse()

	http.HandleFunc("/process", new(PayloadHandler).Handle)
	log.Printf("Listening on port %s...", *port)
	log.Fatal(http.ListenAndServe(":"+*port, nil))
}

次に、認証ロジックを別パッケージとして auth/validator.go に実装する:

package auth

func Validate(username, password string) bool {
	return username == "admin" && password == "admin"
}

重要なポイント

  • go mod init により、モジュールベースの依存管理が有効になる。
  • サブディレクトリ(例: auth)内のGoファイルは、同じパッケージ名(例: package auth)を持つ必要がある。
  • 外部から呼び出される関数(例: Validate)は大文字始まりで公開(exported)にする必要がある。
  • インポートパスはモジュール名+サブディレクトリ名(例: "my_auth/auth")で指定する。

ビルドと実行

$ go build -o auth_server
$ ./auth_server -p 8090

動作確認

認証なしでのリクエスト(失敗):

$ curl -X POST -H "Content-Type: application/json" \
  -d '{"key":"value"}' http://localhost:8090/process
401 Unauthorized

不正な認証情報(失敗):

$ curl -u admin:wrongpass -X POST -H "Content-Type: application/json" \
  -d '{"key":"value"}' http://localhost:8090/process
401 Unauthorized

正しい認証情報(成功):

$ curl -u admin:admin -X POST -H "Content-Type: application/json" \
  -d '{"key":"value"}' http://localhost:8090/process
Payload processed successfully

サーバー側にはペイロードの内容が標準出力される。

タグ: Go BasicAuth HTTP Server Go Modules

8月9日 05:25 投稿