Basic認証
【開発環境】
OS:Win11(64ビット)
go version go1.19.4 windows/amd64
VSCode1.72.2、及びコマンドプロンプト
【Basic認証】
Basic認証は、WEBページに対して最も簡単に導入できる認証方法の一つです
ユーザ名とパスワードの組み合わせで認証を行う
Basic認証の仕組みですが、クライアントからはユーザ名とパスワードの組み合わせをコロン “:” でつなぎ、Base64でエンコードして送信するだけです。
これをサーバ側で受け取り、事前に登録されたユーザ名とパスワードの組み合わせにマッチするかチェックします。
【Basic認証を要求するWEBサーバの実装】
サーバサイドでのBasic認証の取り扱いには、http.Request構造体に実装されているBasicAuthメソッドを使用する
・定義
func (r *Request) BasicAuth() (username, password string, ok bool)
・サンプルコード「sever.go」
package main
import (
"io"
"net/http"
)
// 認証情報を定数で定義
const (
authUser = "user"
authPw = "pass"
)
// 認証関数
func checkAuth(req *http.Request) bool {
// req.BasicAuthメソッドで送信されたユーザ名・パスワードを取得
user, pw, ok := req.BasicAuth()
// 正しいユーザ名・パスワードと比較
if !ok || user != authUser || pw != authPw {
return false
}
return true
}
// Basic認証を行うハンドラ関数
func basicAuthHandler(w http.ResponseWriter, req *http.Request) {
// 認証関数の実行
if checkAuth(req) == false {
// 認証に失敗した場合のヘッダ情報付与
w.Header().Add("WWW-Authenticate", `Basic realm="my private area"`)
w.WriteHeader(http.StatusUnauthorized) // 401コード
// 認証失敗時の出力内容
w.Write([]byte("401 認証失敗\n"))
return
}
// 認証成功時の出力内容
io.WriteString(w, `
<!DOCTYPE html>
<html lang="ja">
<head>
<title>Go | net/httpパッケージ</title>
</head>
<body>
認証成功!
Basic認証で正しいユーザ名とパスワードが送信されました。
</body>
</html>
`)
}
func main() {
// "/"へのリクエストをbasicAuthHandler関数で処理する
http.HandleFunc("/", basicAuthHandler)
// localhost:8080でサーバー処理開始
http.ListenAndServe(":8080", nil)
}
・実行
PS D:\GO言語\サンプルプログラム\Basic認証\sever> go run sever.go
・ブラウザでhttp://localhost:8080/にアクセスする

・入力する
コード内の定数で定めたユーザ名とパスワードを送信する

【Basic認証リクエストの送信】
クライアント側から認証情報を付与してリクエスト送信する方法
http.Request構造体に実装されているSetBasicAuthメソッドにより、送信リクエストのヘッダにBasic認証情報を設定できます。
・定義
func (r *Request) SetBasicAuth(username, password string)
・サンプルコード「client.go」
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httputil"
"net/url"
"time"
)
// 認証情報を定数で定義
const (
authUser = "user"
authPw = "pass"
)
func main() {
// URLを生成
u := &url.URL{}
u.Scheme = "http"
u.Host = "localhost:8080"
// url文字列
uStr := u.String()
// タイムアウトを30秒に指定してClient構造体を生成
cli := &http.Client{Timeout: time.Duration(30) * time.Second}
// 生成したURLを元にRequest構造体を生成
req, _ := http.NewRequest("GET", uStr, nil)
// SetBasicAuthメソッドでBasic認証情報をセット
req.SetBasicAuth(authUser, authPw)
// リクエストヘッダの内容を出力
header, _ := httputil.DumpRequestOut(req, true)
fmt.Println(string(header))
// GETリクエスト発行
rsp, err := cli.Do(req)
if err != nil {
fmt.Println(err)
return
}
// 関数を抜ける際に必ずresponseをcloseするようにdeferでcloseを呼ぶ
defer rsp.Body.Close()
// レスポンスを取得し出力
body, _ := ioutil.ReadAll(rsp.Body)
fmt.Println(string(body))
}
・実行結果

※コメント投稿者のブログIDはブログ作成者のみに通知されます