Go
bootstrap
管理画面
GORM
gin
More than 1 year has passed since last update.

管理画面を作ろう

GoでLINEbotを作った。

その時の記事はこちら。
LINE Messenger APIで作った機能

色々やっていると
やっぱり管理画面が必要になって来る。

そこで、管理画面もGoで作ってみた。


大体の構成

WebサーバはGoのFWでGinを使うことにした。

ORMはgorm。

デザインは面倒なのでbootstrap。

管理画面なので
きちんとセッション管理を入れたい。

API毎にセッションチェックを
しないといけないので
共通ロジックにしてうまいことやりたい。

ということで、早速チャレンジ。


セッション管理

Ginには標準でセッション管理があるらしい。
折角なのでやってみたが、なぜか失敗。

ログイン時にセッションIDを作って
次のアクセスでチェックしてみたが
なぜかSession not foundに・・・

しばらく粘ったができないので
一旦Goのレシーバで実装することにした。


まずはセッション登録

ログインした時にセッションIDを発行し
レシーバ内に保存。

セッションIDは適当なロジックで作成。

作ったIDはクエリパラメータに設定し
以降のアクセスでチェックする。

有効時間を決めて
長くアクセスがない場合には
タイムアウトするようにした。

type Session struct {
    session map[string]int64
}

func (session *Session) CreateSession() (key string) {
    key = sessionKey()
    session.session[key] = sessionTime()
    return
}

func (session *Session) CheckSession(key string) (ok bool) {
    if ok = time.Now().Unix() <= session.session[key]; ok {
        session.session[key] = sessionTime()
        return
    }
    delete(session.session, key)
    return
}

チェックは共通ロジックで

セッションチェックは
どのページでもする必要があるので
全てに入れるのではなく
共通でチェックできるように
専用のHandlerを作った。

func (ms *Botman) SessionHandler(f gin.HandlerFunc) gin.HandlerFunc {
    return func(g *gin.Context) {
        if !ms.session.CheckSession(g.Query(SESSION)) {
            log.Errorf("Session not found: %s", g.Request.URL)
            ms.errorResult(g, http.StatusInternalServerError, errorMessage(SESSION))
            return
        }
        f(g)
        return
    }
}

次にGinのHandler設定部

ハンドラ設定する段階で
共通のセッション管理Handlerを被せる。

セッションチェックしたい場合は
SessionHandlerを被せて登録すればOK。

func HandlerSettings(ctx *system.Ctx) {
    ms := NewBotman(ctx)

    server := gin.Default()
    bm := server.Group(BASEPATH)
    {
        bm.Static(fmt.Sprintf("/%s", PUBLIC), "public")
        bm.GET(fmt.Sprintf("/%s", PING), func(c *gin.Context) {
            c.JSON(http.StatusOK, gin.H{
                CODE: http.StatusOK,
                MSG:  "pong",
            })
        })
        bm.GET(fmt.Sprintf("/%s", LOGIN), ms.LoginGetHandler)
        bm.POST(fmt.Sprintf("/%s", LOGIN), ms.LoginPostHandler)
        bm.GET(fmt.Sprintf("/%s", REPORT), ms.SessionHandler(ms.ReportGetHandler))
        bm.GET(fmt.Sprintf("/%s", CONTENT), ms.SessionHandler(ms.ContentGetHandler))
        bm.POST(fmt.Sprintf("/%s", CONTENT), ms.SessionHandler(ms.ContentPostHandler))
        bm.GET(fmt.Sprintf("/%s", MESSAGE), ms.SessionHandler(ms.MessageGetHandler))
        bm.GET(fmt.Sprintf("/%s", LINELOGIN), ms.LineloginGetHandler)
    }

    server.Run(":{{.Port番号}}")
    return
}

最後に

ただHandlerを被せれば良いだけなので
何も気にしないでページを増やせる (^_^)

だいぶ楽になった。
これでセッション管理はOK。

Ginのセッション管理が
使えなかったことだけが残念。

途中まではうまく行っていた気がしたが
なぜか登録したセッションが
次のアクセスで見れなくなってしまう・・・

そんな事象に心当たりのある方は
是非教えてください!