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
サーバー側にはペイロードの内容が標準出力される。