Original post

Hi all,

I have been learning for around 3 weeks and could do with some help if you have the time!

I am using the following library to manage sessions (I have it working):

https://github.com/rbcervilla/redisstore

It's a pretty small library and the main file is just:

https://github.com/rbcervilla/redisstore/blob/master/redisstore.go

Basically it creates a session and stores it in a redis store, and validates against the store etc.

I have all this working on my api.

Here is my issue:

So I am currently setting a userSessionID value to the session that is passed back via the response to the user. This is unique to a user and will be used to be able to get the user ID for the user (to get user specific data)

Currently in the libraries implementation it stores the sessions in redis like:

"session_UDPTLRXUXTJZMVB2AFWRNJHJQXBR27ZY5KZ7Z3KSIXL6ETQ4KXEIBJA4WEVEQID2WSAFQFKLFOHWYT42PIHUMRNW5RWSS76Z72QS4SI"

However I want to be able to add some more information like: [userSessionID, userID, role, sessionID]

Here is my reasoning as to why I need to store these in the redis store: (besides the faster speed rather than querying the mongodb each request)

userSessionID is sent as a value in the session token to the user. It is used so that we do not have to send the userID, so as to keep that hidden.

By counting the amount of userSessionID objects in the store we can determine how many sessions are existing per user, and can let a user close all other sessions, or close all sessions including this one. We can also set a limit on the amount of sessions allowed per user or per role.

userID is the users unique id in the mongo db which can be determined when a user sends the session token, which has the userSessionID set as a value

role is stored to determine the role of the user for each session, this can be queried by middleware for each request.

sessionID is the unique session id for each existing session. A session has a unique sessionID but can have the same userSessionID as other sessions

Session Concept:

[userSessionID, userID, role, sessionID]

———————————

[534, 40, “user”, 689]

[534, 40, “user”, 690]

[534, 40, “user”, 691]

[534, 40, “user”, 692]

This would be useful because the session token would only ever have the userSessionID stored in it’s value, then when the user tries to get another session, the backend can check the redis store and see how many sessionIDs exist for the supplied userSessionID and determine if too many exist already.

It can also allow the user to close all other sessions besides this one. Or even close all sessions including this one.

By storing the role in the redis store you don’t have to store it in the session and so in the backend you can have a CASBIN middleware to find out the role of each session. If a user gets promoted and has multiple sessions open you can decide to promote all session roles or just promote the current and new ones.

Here is my current sign in:

store := redisSessionInstance.Store session, err := store.Get(c.Request(), "session_") if err != nil { return c.String(http.StatusNotAcceptable, "failed getting session") } // checks if session exists or is new one // only need to set data to its values if it's new if session.IsNew { // TODO check here if too many sessions exist var userSessionID, err = primitive.ObjectIDFromHex(existingUser.UserSessionID.Hex()) if err != nil { fmt.Println("Error getting user session ID") return c.String(http.StatusNotAcceptable, "error getting user session id") } // This is used when calling endpoints to get specific user data session.Values["userSessionID"] = userSessionID.Hex() session.IsNew = false // TODO somehow save the userSessionID to redis along with sessionID so that we can determine which user owns which sessions. // Save session if err = session.Save(c.Request(), c.Response()); err != nil { fmt.Println("failed saving session: ", err) return c.String(http.StatusNotAcceptable, "failed saving session") } 

submitted by /u/golangbeta
[link] [comments]