【Golang】Goa v3でAPIキー認証(APIKyeAuth)を設定する
経緯
GoaのAPIキー認証(APIKeyAuth)の実装例はJWT認証などと比べると数が非常に少なく、さらにv2から仕様が大きく変わっておりv3での具体的な実装例を見つけられなかったため、今回実装してみた例を紹介します。
参考にしたサイト
①goadesign/goa/blob/v3/dsl/security.go
GoaのGithubリポジトリです。大まかな実装例が乗っており、参考になります。
②Goa v1 や Goa v2 から v3 にアップグレードする
v1やv2での実装例をv3に適用する際に参考にしました。
実装
Goa公式のCalculator Serviceのdesign.go
を題材にします。(別オリジンからのリクエストを想定しています。)
package design import ( . "goa.design/goa/v3/dsl" ) var _ = API("calc", func() { Title("Calculator Service") Description("Service for adding numbers, a Goa teaser") Server("calc", func() { Host("localhost", func() { URI("http://localhost:8000") }) }) }) var _ = Service("calc", func() { Description("The calc service performs operations on numbers.") cors.Origin("接続元のURL", func() { cors.Headers("Access-Control-Allow-Origin", "Authorization") cors.Methods("GET") cors.Credentials() }) Method("add", func() { Security(APIKeyAuth) Payload(func() { APIKey("api_key", "key", String, "API key used to perform authorization") Field(1, "a", Int, "Left operand") Field(2, "b", Int, "Right operand") Required("key", "a", "b") }) Result(Int) HTTP(func() { GET("/add/{a}/{b}") Header("key:Authorization") }) }) }) var APIKeyAuth = APIKeySecurity("api_key", func() { Description("Secures endpoint by requiring an API key.") })
順に説明していきます。
var APIKeyAuth = APIKeySecurity("api_key", func() { Description("Secures endpoint by requiring an API key.") })
まず、APIKeyAuthを使用するため、ファイル最下部で以下の変数設定を行っています。
var _ = Service("calc", func() { Description("The calc service performs operations on numbers.") cors.Origin("接続元のURL", func() { cors.Headers("Access-Control-Allow-Origin", "Authorization") cors.Methods("GET") cors.Credentials() })
次に、CORSの設定を行います。ここで、後ほど設定するAPIキーを格納するヘッダーもcors.Headersに追加しておく必要があります(ここではAuthorization
ヘッダー)。これを設定しないとCORSはクリアできてもリクエストヘッダーからAPIキーを取得できません。
Method("add", func() { Security(APIKeyAuth) Payload(func() { APIKey("api_key", "key", String, "API key used to perform authorization") Field(1, "a", Int, "Left operand") Field(2, "b", Int, "Right operand") Required("key", "a", "b") }) Result(Int)
次に、Method
へ記述していきます。まず、このメソッドでAPIキー認証を適用することを宣言するため、Security(APIKeyAuth)
を追加します。次にPayload
内でAPIKey
を記述し、APIキーの変数について定義します。(gRPCで利用する際は、APIKeyField
の設定が必要になるようです。詳しい仕様は以下を参照してください。)
またRequired
に、APIキー用の変数を追加します。
HTTP(func() { GET("/add/{a}/{b}") Header("key:Authorization") })
最後にHTTP
部で、Header
にてAPIキーを格納するヘッダーを設定します。括弧内は、”キー:ヘッダー”の組み合わせです。
以上が、APIキー認証を実装する場合のdesignとなります。