LoginSignup
16

More than 3 years have passed since last update.

Go言語でセッション管理

Last updated at Posted at 2019-04-12

Webアプリケーションの開発をする上で必要になってくる、セッション管理について調べた上で理解したことを書いていく。

セッション管理が何故必要なのか

  • 1 データを保持する必要がある
  • 2 他のユーザーから自分の見ているページを覗かれないようにするため

1

http通信ではクライアントの要求をもとにデータ(基本的にhtml, cssなど)を送信する。データが送信されるとクライントとサーバー間の通信が終わる。そのため、以前入力したデータが保存されない。

2

例えばログインが必要なWebアプリを考える。ユーザーは自身のIDやパスワードを入力しログインすることができるが、ログインしたあと個人情報が記述されているページに移動する場合、自分以外に見られることは好ましくない。そのためログインしたユーザーを識別するためのセッションIDは複雑でユニークな文字列である必要がある。

これらの問題を解決するために、ユーザー管理などが必要なWebアプリケーションではセッション管理をする必要がある。

使うもの

Echoが見たところ実装しやすそうだったのでgo getする。

go get github.com/labstack/echo
go get github.com/labstack/echo-contrib
go get github.com/gorilla/context
go get github.com/dgrijalva/jwt-go

実装

まずはログインするところから。

func login(e *echo.Echo) echo.HandlerFunc{
    e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret"))))
    return func(c echo.Context) error {
        sess, _ := session.Get("session", c)
        sess.Options = &sessions.Options{
            //Path:でsessionの有効な範囲を指定。指定無しで全て有効になる。
            //有効な時間
            MaxAge:   86400 * 7,
            //trueでjsからのアクセス拒否
            HttpOnly: true,
        }
        //テキトウな値
        sess.Values["foo"] = "bar"
        //ログインしました
        sess.Values["auth"] = true
        //状態保存
        if err:=sess.Save(c.Request(), c.Response());err!=nil{
            return c.NoContent(http.StatusInternalServerError)
        }
        return c.NoContent(http.StatusOK)
    }
}       

特に入力することはない。http://[IPアドレス]/loginにアクセスするとSessionを開始する。

次にログインしたときのみ~/secretにアクセスすると bar が表示されるようにする。

func secret() echo.HandlerFunc{
    return func(c echo.Context)error{
        //sessionを見る
        sess, err := session.Get("session", c)
        if err!=nil {
            return c.String(http.StatusInternalServerError, "Error")
        }
        //ログインしているか
        if b, _:=sess.Values["auth"];b!=true{
            return c.String(http.StatusUnauthorized, "401")
        }else {
            return c.String(http.StatusOK, sess.Values["foo"].(string))
        }
    }
}

最後にログアウト

func logout() echo.HandlerFunc{
    return func(c echo.Context) error {
        sess, _ := session.Get("session", c)
        //ログアウト
        sess.Values["auth"]=false
        //状態を保存
        if err:=sess.Save(c.Request(), c.Response());err!=nil{
            return c.NoContent(http.StatusInternalServerError)
        }
        return c.NoContent(http.StatusOK)
    }
}

ログアウトしてから~/secretにアクセスすると401が表示される。

おわりに

今回は基本的なセッション管理のプログラムをしてみた。今後はより複雑なケースを想定してプログラムをしていく。

参考にしたところ

Echo
Go exsample sessions

Githubにソースコード置きました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16