メインコンテンツまでスキップ

ミドルウェア

この章では、Go-Sail でルートミドルウェアを登録する方法について解説します。

はじめに

ルーティングミドルウェアは、リクエストの前処理と後処理の間に位置し、両者の橋渡しをする役割を持ちます。通常、認証などの共通処理はミドルウェアに配置します。
Go-Sail は Gin を HTTP サービスエンジンとして過度なラッピングなしで採用しているため、基本的な使い方は Gin 本家の使用方法と全く同じです。

前章で、ユーザーがログイン成功後にパストークンを発行する方法を紹介しました。以降のリクエストでは、このトークンを用いて認証が必要なリソースへのアクセスが可能になります。

ルートミドルウェアの宣言

まず、Gin の仕様に則ってミドルウェア関数を書いてみましょう。以下のようなコードになります。

ヒント

ユーザーがリクエストヘッダ内に認証情報を付与しており、そのフィールド名は "Authorization" であることを前提としています。

main.go
package main

import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/constants"
"github.com/keepchen/go-sail/v3/sail"
)

...

// ValidateToken ユーザーのトークンを検証する
func ValidateToken() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.Request.Header.Get("Authorization")
if token != "this-is-a-valid-token" {
sail.Response(c).Wrap(constants.ErrAuthorizationTokenInvalid, nil).Send()
return
}

c.Next()
}
}

...

ルートでのミドルウェア使用

次に、認証が必要なルートをまとめてラップし、同じ認証処理を統一的に利用できるようにします。

main.go
package main

import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
)
var (
...

registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
var loginRequest LoginRequest
c.ShouldBind(&loginRequest)

if loginRequest.Username != "go-sail" || loginRequest.Password != "password" {
sail.Response(c).Failure("login failed, username or password not match!")
return
}

token := "this-is-a-valid-token"
sail.Response(c).Data(token)
})
userGroup := ginEngine.Group("/user").Use(ValidateToken())
{
userGroup.GET("/balance", ...).
GET("/info", ...).
GET("/logout", ...)
}
}
...
)

ハイライトされているコードは、/user/balance/user/info/user/logout というルートにアクセスするには認証が必要であることを示しています。