HTTP Basic認証の概要とGo標準パッケージnet/http
を用いた実装をまとめる。
BASIC認証とは
HTTPで定義される認証方式の一つ。
クライアントは、クライアントID(ユーザー名)とクライアントシークレット(パスワード)の組み合わせをコロン “:” でつなぎ、Base64エンコードした値を、Authorizationヘッダーにセットしてサーバーへ送信する。
これをサーバー側は受け取り、事前に登録されたクライアントIDとクライアントシークレットの組み合わせに一致するか検証する。一致した場合は、リクエストを処理する。一致しなかった場合は、ステータスコード401を返却する。
Go標準パッケージnet/http
での実装
クライアント側
client.go
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
func main() {
// クライアント生成
client := &http.Client{Timeout: time.Duration(30) * time.Second}
// リクエスト定義
req, err := http.NewRequest("GET", "http://localhost:8080/basic_auth", nil)
if err != nil {
log.Fatal(err)
}
// 認証情報をセット
req.SetBasicAuth("client_id", "client_secret")
// リクエスト実行
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
サーバー側
server.go
package main
import (
"fmt"
"log"
"net/http"
)
// Basic認証
func checkAuth(r *http.Request) bool {
// 認証情報取得
clientID, clientSecret, ok := r.BasicAuth()
if ok == false {
return false
}
return clientID == "client_id" && clientSecret == "client_secret"
}
func main() {
http.HandleFunc("/basic_auth",
func(w http.ResponseWriter, r *http.Request) {
// 認証失敗時
if checkAuth(r) == false {
w.Header().Add("WWW-Authenticate", `Basic realm="SECRET AREA"`)
w.WriteHeader(http.StatusUnauthorized) // 401
http.Error(w, "Unauthorized", 401)
return
}
_, err := fmt.Fprintf(w, "Successful Basic Authentication \n")
if err != nil {
log.Fatal(err)
}
},
)
log.Println(http.ListenAndServe(":8080", nil))
}