sessions icon indicating copy to clipboard operation
sessions copied to clipboard

How to access a session without request context?

Open bestplay opened this issue 6 years ago • 6 comments

When user login.

I want to kick off the previous session of the same user ?

If using redistore,

It seems like i can't access the session.ID

Any help

bestplay avatar Jan 25 '18 13:01 bestplay

+1 I was just wondering the same thing. this is very confusing to a newcomer

zwhitchcox avatar May 21 '18 21:05 zwhitchcox

For what use case do you want to know session's own ID? The so-called “session” is linked to each browser/PC. So, when the client sends the same cookie, the same session is returned by s := sessions.Default(c). Probably this s has ID or so, but you need not to know it when you use the data from session.

If you want to know the user-related data over other requests, it is not the use case for “session”. You should use other method to know that.

This example below shows the way to know userID from session, and user-related data from DB.

// user must access here before getting his/her info
func LoginHandler(c *gin.Context) {
  username := c.Form("username")
  password := c.Form("password")
  // in case user data is stored into DB...
  user, err := GetUserFromDB(username, password)
  if err != nil { ... }
  // Sessions might be stored in cookie, redis, and so on.
  // You need not to worry about where sessions live in.
  s := sessions.Default(c)
  s.Set("userID", user.ID)
  _ = s.Save()
  c.JSON(http.StatusOK, gin.H{"result": "OK"})
}

// this handler expects the session has userID, that is,
// the client has accessed LoginHandler before this.
func GetUserInfoHandler(c *gin.Context) {
  userID, ok := sessions.Default(c).Get("userID").(int64)
  if !ok {
    panic("not logged-in")
  }
  user, err := GetUserByIDFromDB(userID)
  if err != nil { ... }
  c.JSON(http.StatusOK, gin.H{"userInfo": user})
}

In addition to that, you should not know the session ID for a security reason. In general sessions has much sensitive data for users. You should not fetch those data freely even if you are admin. So each session's ID is encrypted into cookie by gorilla/securecookie package, and the logic to decrypt it is hidden into the sessions package. I think you may follow the way.

delphinus avatar May 22 '18 01:05 delphinus

This does not work for me. Each session is on a different route and therefore a different context. So, there's no way to get the "user_id" in your example across the different routes. I don't know, maybe there is a way around this that I'm not seeing though. But in one route, the sessions.Default(c).Get("user_id") code would be nil, and the login would have the correct user id.

zwhitchcox avatar May 22 '18 01:05 zwhitchcox

This package (internal package gorilla/sessions in accurate) uses the cookie from the client to detect the session throughout multi requests. If the user (and the browser) is the same, he/she sends the same cookie in each request. So this package can know the same session from it.

But what the cookie has? It has an encrypted ID of the session. It is highly secure encryption, so it is much difficult you decrypt it and know the just ID of the session.

sessions.Default(c) hides this encryption/decryption phase in it. After you call s.Set("userID", ID), and s.Save(), you can always get the userID by sessions.Default(c).Get("userID") in other requests because the client always sends the same cookie to the server. Conversely speaking, if the client deletes the cookie, the data in the session are lost permanently.

I think this might be written somewhere in README...

delphinus avatar May 22 '18 01:05 delphinus

When you choose cookie.Store, redis.Store, memcached.Store, and so on, the ID of the session is always stored in the cookie. And the data in the session, such as userID, are stored into the place you chosen, cookie, redis, memcache, and so on. It is a bit confusing, maybe.

delphinus avatar May 22 '18 02:05 delphinus

Ok, I guess I am talking about something different than OP...my problem was I was using fetch, which doesn't include cookies by default. I thought there was a different gin context for some reason, because of my testing. My mistake!! XD

zwhitchcox avatar May 22 '18 02:05 zwhitchcox