Ginを使ったGo API開発の初歩(Basic認証編)

以下の記事でGinをインストールしてGo APIの実装を始めました。今日はBasic認証を導入し、ユーザーIDとパスワードが必要なAPIを実装します。

Ginを使ったGo API開発の初歩

  • Basic認証とは
  • Basic認証の実装
  • APIの確認

Basic認証とは


Basic認証とは、httpリクエストにおける認証システムです。以下の画面のようにユーザーIDとパスワードを求められたことがあると思います。あらかじめ登録されたユーザーIDとパスワードを入力するとアクセスできる仕組みです。

Basic認証の実装


実装サンプルを参考に、Basic認証を実装します。

リンク先のサンプルコードでは、認証されたユーザーの秘匿情報を返すように実装されていますが、今回はわかりやすく認証されたら適当な値を返すだけのbasic_auth.goを作成します。

package main

import "github.com/gin-gonic/gin"

func main() {
  r := gin.Default()

  authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
    "koratta":    "koratta",
    "koratta2":   "koratta2",
  }))

  authorized.GET("/hello", func(c *gin.Context) {
    user := c.MustGet(gin.AuthUserKey).(string)
    c.JSON(200, gin.H{ "message": "Hello " + user })
  })

  r.Run(":8080")
}

gin.Accountsでは、[ユーザー名]:[パスワード]のJson形式で認証情報を定義しています。その認証情報と/adminプレフィックスによってauthorizedグループを作成します。このGroupからauthorized.Getで作成されたエンドポイントは、定義された認証情報を持つユーザーのみがアクセスできます。admin/helloエンドポイントは、ユーザー名をメッセージに追加してJsonフォーマットで表示します。

APIの確認


basic_auth.goを実行して、APIを確認します。

$ go run basic_auth.go 
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /admin/hello              --> main.main.func1 (4 handlers)
[GIN-debug] Listening and serving HTTP on :8080

curlコマンドを使ってAPIにリクエストを行います。-uオプションを使うことでユーザー名とパスワードを入力することができます。以下のように、basic_auth.goに登録されているkoratta, koratta2のみリクエストが返ってきてることがわかります。

$ curl -u koratta:koratta localhost:8080/admin/hello
{"message":"Hello koratta"}
$ curl -u koratta2:koratta2 localhost:8080/admin/hello
{"message":"Hello koratta2"}
$ curl -u koratta3:koratta3 localhost:8080/admin/hello
$ 

Ginのログを確認しても、3回目にリクエストを行ったkoratta3のみ、ステータスコード401を返していることがわかります。

[GIN] 2020/07/12 - 16:23:51 | 200 |     116.147µs |             ::1 | GET      "/admin/hello"
[GIN] 2020/07/12 - 16:24:19 | 200 |        67.2µs |             ::1 | GET      "/admin/hello"
[GIN] 2020/07/12 - 16:24:28 | 401 |      52.325µs |             ::1 | GET      "/admin/hello"