Go-Swaggerと認証

こんにちは。若原です。

go-swaggerを使うと、簡単にAPIを作成することができますね。

go-swaggerの使い方はぐぐるとたくさん出てきるので
私が手間取った、RequestHeaderに載ったAPIキーを解析してユーザー情報を得て、全てのAPIにその情報を渡すまでを書いていきます。

1. yamlを定義する

下記の様にswagger.yamlを書きます。

swagger: "2.0"
info:
  version: "1.0.0"
  title: "otameshi-swagger"
host: "localhost:8080"
schemes:
  - "https"
consumes:
  - "application/json"
produces:
  - "application/json"
  - "text/plain"
securityDefinitions: //検証したいRequest Headerの情報を載せていきます
  ApiKeyAuth:
    type: apiKey
    in: header
    name: x-jwt  // 検証したいRequest Headerのキーの名前
security:
  // 検証コードが全てのAPIの処理に行く前に通過させる空配列をいれる
  // 特定のAPIのみに検証コードを通過する様にも設定ができます!
  - ApiKeyAuth: []
paths:
  /user:
    get:
      summary: "Get user"
      tags: ["User"]
      responses:
        200:
          description: Success
          schema:
            $ref: "#/definitions/UserResponse"
definitions:
  UserResponse:
    type: object
    properties:
      id:
        type: string
      email:
        type: string
      name:
        type: string
  principal:
    // RequestHeaderに載ったAPIキーを解析して得たユーザー情報を入れる器です
    // このモデルが全てのAPIに伝えられる
    type: object
    properties:
      userId:
        type: string

2. コマンドをたたく

下記のコマンドをたたいてコードを生成します。

$ swagger generate server -f swagger.yaml --principal models.Principal

3. コードを書き足す

configure.goのconfigureAPI()の中のapi.KeyAuthの中にtokenを検証するコードを書いていきます。
api.KeyAuthの引数にはリクエストヘッダーに載せたAPIキー(今回ならばx-jwt)の値がセットされます。
(実際に検証するコードは割愛します。)
この時、返り値に書いたmodel.Principalが全てのAPIのメソッドに渡っていきます。

...
func configureAPI(api *operations.OtameshiSwaggerAPI) http.Handler {
	...

	api.KeyAuth = func(token string) (*models.Principal, error) {
      isValid, err := isValidToken(token)
      if isValid != true {
        return nil, err
      }
      result := parse(token)
      return result, nil
	}

	api.UserGetUserHandler = user.GetUserHandlerFunc(func(params user.GetUserParams, principal *models.Principal) middleware.Responder {
		return middleware.NotImplemented("operation user.GetUser has not yet been implemented")
	})

...
}

感想

Golang初心者としては、go-swaggerでコードがある程度生成されるのですごくありがたいです。