Nugget post: Registering interfaces with Gin-gonic Sessions

When building a Gin-gonic based web application, you’ll probably come across a situation where you’d like to store information about the request in a session – essentially anything that requires HTTP cookies. Gin+gonic provides the “sessions” middleware to address this:

https://github.com/gin-contrib/sessions

Gin middleware for session management with multi-backend support:

- cookie-based
- Redis
- memcached
- MongoDB
- memstore

The examples are pretty straightforward, and it is indeed simple if you store primitives like int or string in your session. However, if you try to store a more complex object like a struct in your sessions it simply won’t work.

The reason is that sessions does not know how to encode a custom struct. Sessions uses the “gob” encoding package under the hood, and the documentation of gob offers a clue:

Interface values are transmitted as a string identifying the concrete type being sent (a name that must be pre-defined by calling Register)

https://golang.org/pkg/encoding/gob/

So, assuming a custom struct “User”:

type User struct {
	Username     string
	EmailAddress string
}

We first need to “register” the struct with gob:

gob.Register(User{})

Which then allows us to use sessions exactly as prescribed in the documentation examples:

...
// saving a user struct to sessions cookie
var user User 
session.Set("user", user)
...

// retrieving a user from sessions cookie
func getUser(c *gin.Context) {
 session := sessions.Default(c)
 user := session.Get("user").(dbModels.User)
}