sessions icon indicating copy to clipboard operation
sessions copied to clipboard

Different stores for many sessions

Open dusansimic opened this issue 3 years ago • 8 comments

User can create many sessions using SessionsMany() supplying array of names for sessions. The problem is that the same store is used for that. I'd like to use store A for session A and store B for session B. Could this feature be implemented without breaking current API?

dusansimic avatar Sep 16 '20 21:09 dusansimic

@dusansimic I have been playing with this in a fork as I needed exactly this.

My use case is:

Cookies for CSRF Redis for user session

type SessionStore struct {
	Name  string
	Store Store
}

func SessionsMany(sessionStores []SessionStore) gin.HandlerFunc {
	return func(c *gin.Context) {
		sessions := make(map[string]Session, len(sessionStores))
		for _, sessionStore := range sessionStores {
			sessions[sessionStore.Name] = &session{sessionStore.Name, c.Request, sessionStore.Store, nil, false, c.Writer}
		}
		c.Set(DefaultKey, sessions)
		defer context.Clear(c.Request)
		c.Next()
	}
}

It's basically a stand-in replacement for the current SessionsMany although obviously, the types differ so it should probably be a separate helper method to keep backwards compatibility.

An example of using it would be:

	store, err := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("session_secret"), []byte("encryption_secret"))
	if err != nil {
		log.Fatalf("Could not connect to session database: %s", err)
	}
	store.Options(sessions.Options{
		Path:     "/",
		MaxAge:   60 * 60 * 24, // 1 days
		HttpOnly: true,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})

	cookieStore := cookie.NewStore([]byte("session_secret"), []byte("encryption_secret"))
	cookieStore.Options(sessions.Options{
		Path:     "/",
		MaxAge:   60 * 60 * 24 * 30, // 30 days
		HttpOnly: true,
		Secure:   true,
		SameSite: http.SameSiteStrictMode,
	})
		sessionStores := []sessions.SessionStore{
		{
			Name:  "session",
			Store: cookieStore,
		},
		{
			Name:  "user_session",
			Store: store,
		},
	}
	httpRouter.Use(sessions.SessionsMany(sessionStores))

Happy to raise a PR if at least someone else wants this still

srbry avatar Dec 20 '21 16:12 srbry

@appleboy Apologies for tagging you directly but you seem to be one of the more active maintainers.

Is this something you would entertain being added? Do you have any preference on a name for the new helper function that would enable it?

srbry avatar Dec 20 '21 16:12 srbry

@srbry Send the PR first.

appleboy avatar Dec 21 '21 10:12 appleboy

@appleboy Sure thing. I have raised: https://github.com/gin-contrib/sessions/pull/144

Happy to make any changes if required

srbry avatar Dec 21 '21 14:12 srbry

@appleboy have you had a chance to look at this at all yet?

srbry avatar Jan 06 '22 12:01 srbry

@srbry I will take a look this weekend.

appleboy avatar Jan 06 '22 23:01 appleboy

@appleboy When can I see this one?

avexbesuke avatar Apr 05 '23 02:04 avexbesuke

@avexbesuke We need @srbry to fix the conflicts first.

appleboy avatar Apr 05 '23 02:04 appleboy