Giter Site home page Giter Site logo

gorilla / sessions Goto Github PK

View Code? Open in Web Editor NEW
2.8K 57.0 368.0 107 KB

Package gorilla/sessions provides cookie and filesystem sessions and infrastructure for custom session backends.

Home Page: https://gorilla.github.io

License: BSD 3-Clause "New" or "Revised" License

Go 97.50% Makefile 2.50%
gorilla cookie go golang gorilla-web-toolkit sessions

sessions's People

Contributors

adamjack avatar ancarda avatar boj avatar collinewait avatar coreydaley avatar dchest avatar dsoprea avatar elithrar avatar enumappstore avatar kisielk avatar kliron avatar leitzler avatar mariusor avatar michaeljs1990 avatar moraes avatar nikhita avatar nwidger avatar quasoft avatar rbcervilla avatar rcadena avatar ryicoh avatar shawnps avatar stapelberg avatar stephenafamo avatar tbpg avatar thurt avatar tortuoise avatar vdemario avatar yosssi avatar zemirco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sessions's Issues

Would the file created by FilesystemStore will be deleted automatically?

Same as title.

I found a problem and I want to check if my thought is right.

If I use FilesystemStore and set the expired time for that session, the cookie will be deleted when time is up, but the file created by FilesystemStore will still exist.

Is it will be deleted later ? Or all the session files will not be deleted forever ?

Not able to delete sessions by setting MaxAge = -1

It's possible I'm doing something wrong, but I can't seem to find any documentation that shows a different approach.

Here is my initialization code:
(1)

  cookieStore = sessions.NewCookieStore(
    []byte(securecookie.GenerateRandomKey(64))[:64],
    []byte(securecookie.GenerateRandomKey(32))[:32])
  cookieStore.Options = &sessions.Options{
    MaxAge:   86400 * 7, // Session valid for one week.
    HttpOnly: true,
  }

Here's how sessions are added to the cookie store:
(2)


  c := appengine.NewContext(r)
  s, _ := cookieStore.Get(r, SessionName)

  if s.IsNew {

    _, ok := s.Values[sessionUserKey]

    if !ok {

      log.Debugf(c, "adding user to session")
      s.Values[sessionUserKey] = *u
      err := s.Save(r, w)
      if err != nil {
        log.Errorf(c, "Cannot save session: %s", err)
      }

    } else {
      log.Debugf(c, "user already exists in session")
    }
  }

and here is the code that fails to delete the users session:
(3)

  c := appengine.NewContext(r)

  s, _ := cookieStore.Get(r, SessionName)
  s.Options = &sessions.Options{
    MaxAge: -1,
  } 
  // s.Options.MaxAge = -1
  // Alternate syntax I've tried, exactly the same behavior.
  err := s.Save(r, w)
  if err != nil {
    log.Errorf(appengine.NewContext(r), "Cannot save session: %s", err)
  }

  v, ok := s.Values[sessionUserKey]
  if !ok {
    log.Debugf(c, "no user found in current session")
  } else {
    log.Debugf(c, "found user: %v", v)
  }

  http.SetCookie(w, &http.Cookie{Name: GtokenCookieName, MaxAge: -1})

The behavior is oddly inconsistent, if I attempt to delete the session immediately after creating it, it will deleted, but if I then create another session by signing in to my site with the same user account, subsequent attempts to delete the session will fail. If repeatedly run code segment (3) it will log a user object every time.

I have found a few circumstances in which the code will appear to delete the session, but upon running it again the session will reappear, Not sure what that says about the underlying issue, but it is peculiar.

Filesystem store without using cookies?

I am developing a web application which is used by paranoid people who turn off cookies by default and things like that.

Given that the cookie only stores a session identifier, I could just pass that identifier as a hidden field in my form. However, the current API of FilesystemStore does not allow that, it always wants to set/get a cookie.

Aside from setting the cookies before calling the API and deleting the cookie which is returned, would you be open to adding a way to use the FilesystemStore without cookies?

How to clear another user session ?

From an admin interface in a website, I can disable a user, and in that case, I would like also to remove his current session, in order to disconnect him instantly.

From what I see I can only access the session with http.Request, but in that case I don't want to access my session but the one from another user. Can I do that ?

(I know I can also check the database each time I get a session to see if the user is disabled, but I wonder if it's possible without a db access)

flashes - types change to pointer types across requests

(Note: The "Community" tab on the Gorilla toolkit website links directly to the Google group. I posted there first before noticing that there had been no activity for 8 months.)

I've pasted in an example webserver below. I hope that I've extracted a sufficiently small example to illustrate.

  • Retrieving the session flashes during the request that a flash message was added ( http:localhost:10000/add-flash-then-pop ) gives a slice containing a userMessage struct
  • Retrieving the session flashes during a subsequent request after a flash message was added ( http:localhost:10000/add-flash-then-redirect ) gives a slice containing a pointer to a userMessage struct

A type assertion that works for one of these circumstances obviously fails in the other. (The example below will panic at the type assertion after the redirect.)

Please would you tell me whether I'm doing something wrong and, if so, what?

package main

import (
    "encoding/gob"
    "fmt"
    "net/http"

    "github.com/gorilla/sessions"
)

type userMessage struct {
    Type    string
    Message string
}

var store = sessions.NewCookieStore([]byte("something-very-secret"))

func init() {
    gob.Register(&userMessage{})
}

func getSession(w http.ResponseWriter, r *http.Request) *sessions.Session {
    // Get a session. We're ignoring the error resulted from decoding an
    // existing session: Get() always returns a session, even if empty.
    session, err := store.Get(r, "the-magically-changing-types-session")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        panic("No session!")
    }

    return session
}

func addFlash(w http.ResponseWriter, r *http.Request, Type, message string) {
    session := getSession(w, r)
    session.AddFlash(userMessage{Type, message})
    session.Save(r, w)
}

func popAndPrintFlashes(w http.ResponseWriter, r *http.Request) {
    session := getSession(w, r)
    flashes := session.Flashes()
    session.Save(r, w)
    fmt.Println(flashes)
    for _, f := range flashes {
        message := f.(userMessage)  // !!!!! Type assertion. Cross your fingers !!!!!
        fmt.Println(message)
    }
}

func addFlashThenPop(w http.ResponseWriter, r *http.Request) {
    addFlash(w, r, "notice", "I reckon this should work")
    popAndPrintFlashes(w, r)
}

func addFlashThenRedirect(w http.ResponseWriter, r *http.Request) {
    addFlash(w, r, "warning", "I have a bad feeling about this")
    http.Redirect(w, r, "/pop-flashes-after-redirect", http.StatusSeeOther)
}

func popFlashesAfterRedirect(w http.ResponseWriter, r *http.Request) {
    popAndPrintFlashes(w, r)
}

func main() {
    http.HandleFunc("/add-flash-then-pop", addFlashThenPop)
    http.HandleFunc("/add-flash-then-redirect", addFlashThenRedirect)
    http.HandleFunc("/pop-flashes-after-redirect", popFlashesAfterRedirect)
    http.ListenAndServe(":10000", nil)
}

Saving session into request

Is there an recommended way for adding the session values into a request? I need this for my unittests.

I ended up implemented an util function that largely resembles https://github.com/gorilla/sessions/blob/master/store.go#L105, see below:

func testUtilAddSessionValuesToRequest(r *http.Request, values map[interface{}]interface{}) {
    encoded, err := securecookie.EncodeMulti("session-name", values, store.Codecs...)
    if err != nil {
        return err    
    }
    r.AddCookie(sessions.NewCookie("session-name", encoded, store.Options))
    return nil
}

Not sure if this is the best approach though. Can anyone advice?

Thanks.

Question about modifying sessions

It seems that whenever I call Save(r, w) after modifying a session, the session store will create a new session. Do I have to manually remove the previous session by setting its age to -1?

Sorry, I'm fairly new to sessions in general, and I was just a bit confused because there isn't a convenient Delete() method so I was unsure of how to approach this. I guess what I'm asking is a general question about managing modified sessions (and deleting the previous one?) whether it be using php, rails, etc.

Add Close() to Store interface.

Adding a Close() function to the Store interface facilitates cleanup of custom backends without breaking from the API. If maintainers are in support, I can put together a PR.

FilesystemStore has an unnecessary hard limit of 4096 bytes for values

From http://code.google.com/p/gorilla/issues/detail?id=55

A user reported that he could not use my web application:
http://article.gmane.org/gmane.comp.window-managers.i3.general/679

After looking into it, the problem is that the sessions.FilesystemStore is unable to encode sessions whose serialized base64 representation exceeds 4096 bytes due to the FilesystemStore using securecookie internally (which has a 4096 byte limitation by default).

I am working around this with the patch I attached (to make the issue more clear if my description is not enough).

To reproduce this issue, it is enough to store a 4097 byte value in your session.

Third Party Stores Not Applying Options to Codecs correctly.

We just upgraded this package and it's not setting cookies correctly. It's setting stuff like _ga=GA1.1.922831813.14264788986 instead of the regular base64 encoded cookie data. Any idea whats going on or when this broke so we can revert back to a working version? Thanks!

Is there an example of how to use struct as a type for sessions flash messages?

This is what I tried so far, the problem is I get no flash messages from session.Flashes(),
after visiting /flash and redirected to /.

package main

import (
    "fmt"
    "github.com/gorilla/securecookie"
    "github.com/gorilla/sessions"
    "log"
    "net/http"
)

const (
    empty = iota
    notice
)

type Flash struct {
    Type    int
    Message string
}

var cookies = sessions.NewCookieStore(
    securecookie.GenerateRandomKey(32),
    securecookie.GenerateRandomKey(32),
)

func main() {
    http.HandleFunc("/", index)
    http.HandleFunc("/flash", addFlash)

    fmt.Println("listen and serve on port: 3000 ...")
    log.Fatal(http.ListenAndServe(":3000", nil))
}

func index(w http.ResponseWriter, r *http.Request) {
    session, _ := cookies.Get(r, "flash-session")
    flashes := session.Flashes()
    session.Save(r, w)
    log.Println(flashes)
    if len(flashes) > 0 {
        flash := flashes[0].(Flash)
        fmt.Fprintln(w, flash.Message)
    }

    fmt.Fprintln(w, "Hello, World!")
}

func addFlash(w http.ResponseWriter, r *http.Request) {
    session, _ := cookies.Get(r, "flash-session")
    flash := Flash{
        Type:    notice,
        Message: "flash message",
    }
    session.AddFlash(flash)

    session.Save(r, w)
    http.Redirect(w, r, "/", http.StatusSeeOther)
}

':' character in session name causes session cookie to not be written

session, err := conf.SessionStore.Get(r, "myapp:session")
session.Values["foo"] = "bar"
if err := session.Save(r, w); err != nil {
    freakOut()
}

The above code does not produce any errors. The session cookie is never written though. No idea why. Replacing "myapp:session" with "myapp-session" fixes the problem.

Not sure if this is something specific to gorilla session but as far as I know illegal characters for cookie names include whitespace, comma and semicolon but not colon. It would be nice if Get() would do a sanity check on cookie names and fail with an error in such a case.

Store.Get permits invalid cookie names

I encountered this problem in the following fashion:

func Session(r *http.Request) *sessions.Session {
    sess, err := sessionStore.Get(r, "invalid cookie name")
    if err != nil {
        panic(err)
    }

    return sess
}

I could not retrieve session data saved in this way. It turns out that spaces are disallowed in cookie names[1] - and Gorilla's session store name directly corresponds with a cookie name. Removing the spaces (in this case, converting "invalid cookie name" into "invalidcookiename") solves the problem.

I would propose either that internally, this method convert the value into a valid cookie name (suboptimal because then it doesn't reflect what the creator passed it) or that it trigger an error if an invalid cookie name gets passed to it.

1 = http://stackoverflow.com/a/1969339/199475

question about "wrap your handlers with context.ClearHandler as or else you will leak memory"

There is an important note in the doc http://www.gorillatoolkit.org/pkg/sessions

Important Note: If you aren't using gorilla/mux, you need to wrap your handlers with 
context.ClearHandler as or else you will leak memory! An easy way to do this is to 
wrap the top-level mux when calling http.ListenAndServe:

http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))

I checked the code. context.ClearHandler just calls context.Clear which modifies local variables. https://github.com/gorilla/context/blob/master/context.go#L91-L105

Sounds like we don't need to wrap handlers with context.ClearHandler if not using gorilla/mux. Is it correct?

Store.Save should return error if ResponseWriter.Write has been called

Not sure if this is something to be handled at the Store.Save level or if people should just exercise caution, but, what about returning an error on Save if the ResponseWriter.Write has been called?

See relevant line here: https://github.com/gorilla/sessions/blob/master/store.go#L101

Here's one example of someone who ran into a problem because they were unaware that they should call Save before writing to the response.

http://stackoverflow.com/questions/21865681/sessions-variables-in-golang-not-saved-while-using-gorilla-sessions

Relevant godoc here: http://golang.org/src/net/http/server.go?s=1500:2376#L70

I'm not sure what the correct check should be though.

Happy to work on a PR if you think this is a worthwhile enhancement.

Add Remove to Store

Current implementation allows removing sessions by setting their MaxAge to a negative value.
This is rather cryptic and not really explicit.
Adding Remove to Store interface seems quite logical.
It'd probably use a signature similar to Save and just set MaxAge.

Thanks,
Andrew.

Stock CookieStore and FilesystemStore do not copy their default Options to the sessions they create correctly.

For example, if you look at line 76 of store.go, you see.

session.Options = &(*s.Options)

Because Sessions already have a pointer to their store object, I believe the intent here is to copy the options in the store to the options in the session being created so that the options in the created session can be changed without affecting the default options in the store. Unfortunately, this code makes session.Options point to the store's options so that changing the options in a session instance is the same as changing the options in the store. This could lead to multiple goroutines inadvertently changing the Options in the same store without protection from a mutex resulting in unexpected behavior.

Instead do this:

defaultOptions := *s.Options
session.Options := &defaultOptions

That ensures that the options are actually copied from the store.

Session expiration func

It would be nice is there was an expire func that in the case of cookie sessions set the cookie lifetime to a time in the past. Let me know what you think.

FilesystemStore doesn’t truncate session files

From http://code.google.com/p/gorilla/issues/detail?id=53

I’m writing a small web-app and I noticed that during testing, I sometimes got the error message

"2012/09/27 15:25:50 session error: securecookie: the value could not be decoded"

…and my session contents were lost.

After a bit of digging, this happens when you write session contents which are smaller than the previous contents.

It can be easily fixed by using os.O_TRUNC in func (s *FilesystemStore) save(session *Session) (sessions/store.go:198):

fp, err2 := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)

Please apply this fix upstream.

Thanks!

Session Store stores in values in cookie as well

Hi,

I was building a session store with couchbase. code is available at https://github.com/srinathgs/couchbasestore

I would want only the session ID or encryption key alone to be stored in the cookie. The session values shall be stored in the couchbase only.

Currently, the code writes to the cookie as well. I think it is because of the code in https://github.com/srinathgs/couchbasestore/blob/master/couchbasestore.go#L80

Is there any way to store only the session id in cookie?

securecookie: the value is not valid

Hi,
I get this error when trying to call store.Get() on a request from websocket.Conn.Request()

session, err := store.Get(conn.Request(), "my_session")

The error originates from the verifyMac function of gorilla/securecookie.

Race condition in FilesystemStore

There is a race condition in FilesystemStore that I intend to fix but I would like your input before I go ahead and do it. Basically the problem is that if you have concurrent requests from the same user (same session) that the following is possible:

  1. Request 1 opens the session to perform a semi long operation
  2. Request 2 opens the session
  3. Request 2 Removes session data to perform "logout" or similar
  4. Request 2 saves
  5. Request 1 saves, which makes it as if the session was never logged out

I have added a test case for this flaw at cless/sessions@f84abed

The most straight forward way to fix this would be by introducing locks at the file system level. However, golang has no cross platform way to do file locking. It does expose flock in syscall but that only works if the OS supports it. I believe the behavior of flock might also be different on different unixes although I am not sure that this is the case. Another issue with flock is that it might not work on NFS.

An entirely different solution would be to keep a map of locks in the FilesystemStore object itself. This has another set of disadvantages: You can't have multiple processes access the same file system sessions and you can't create multiple stores for the same file system session within a single application. However, both these things are already impossible to do without causing issues.

In the end, I think the best solution is to keep a map of locks in the store object because all the disadvantages in that scenario can be properly documented and you can reply on the behavior being the same across different systems.

Other storage backends that are based on FilesystemStore might copy this flaw (I noticed this issue when reviewing Redistore code for a project of mine boj/redistore#2)

Cookie expiration

Is it possible to honor a login remember me checkbox? If the user wants not to be remember how can I set this to the cookie store?

Create a new Filesystem backed session if a match can't be found

I'm using the Filesystem session store, and emptied my session directory after creating a session to see what would happen. The log message looked like this:

2013/01/30 00:42:44 open /Users/gtaylor/Documents/workspace/gopath/src/monweb/sessions/session_5A5RY546OOHJUSK5DEVARK7LFUW2NRLCNMC2V2TS2AVQ4GB22ZBA: no such file or directory

Perhaps it would be a good idea to create a new session instead of a hard failure? This appears to currently be an unrecoverable error, since the user has a cookie set with the session ID, but the match always fails.

Go 1.7: http.Request.Context breaks gorilla/context usage

The new http.Request.Context() in Go 1.7 creates a shallow copy of the original request that requires the caller to save it upstream. This copy has a different address and therefore has a different map key in the context map provided by gorilla/context.

In order to fix this in gorilla/sessions we need to make a breaking change for Go 1.7+ users:

- func GetRegistry(r *http.Request) *Registry {
+ func GetRegistry(r *http.Request) (*Registry, *http.Request)
- sessions.GetRegistry(r).Get(s, name)
+ var reg *sessions.Registry
+ reg, r = sessions.GetRegistry(r)
+ sess, err := reg.Get(store, name)

That should be about it. This is unavoidable unfortunately, but is (thankfully) a compile-time breaking change that we can document clearly.

Ref: gorilla/mux#168

Filesystem store question

Does this leak file descriptors? (most comments mine)

// save writes encoded session.Values to a file.
func (s *FilesystemStore) save(session *Session) error {
    // - snip -
    fp, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
        return err
    }
    // Now we have an open file
    if _, err = fp.Write([]byte(encoded)); err != nil {
        return err // <----------------- Fail a write and return without Closing
    }
    fp.Close() // Safely close the file
    return nil
}

sessions.FilesystemStore doesn't implement sessions.Store

I'm trying to write a piece of middleware that accepts a sessions.Store supplied by the application, and I'm getting errors any time I try to pass a sessions.FilesystemStore. This simplified snippet:

package main

import (
    "fmt"
    "github.com/gorilla/sessions"
)

func printStore(store sessions.Store) {
    fmt.Printf("%v", store)
}

func main() {
    // set up FilesystemStore
    fsStore := sessions.NewFilesystemStore("", []byte("some key"))
    fsStore.MaxLength(0)

    // print it
    printStore(*fsStore)
}

gets me this output:

[dab178@bonnerbook src]$ go run foo.go
# command-line-arguments
./foo.go:18: cannot use *fsStore (type sessions.FilesystemStore) as type sessions.Store in argument to printStore:
        sessions.FilesystemStore does not implement sessions.Store (Get method has pointer receiver)

I'm new to go, and am more than happy to find out I'm just missing a cast somewhere, but the error message go run gives makes me think it's not just me.

Error setting and retrieving session

Route: /login
When sending a POST it correctly authenticates. It then redirects you to /team/teamPage.
Expected: When going to /team/teamPage if you have a valid session then you will end up going to /teamPage.html,which is currently blank, if not you will be redirected back to login.html

Problem: When successfully logging in I still get redirected back to /login.html by the RequireLogin function which is not suppose to happen after a successful login.

These are the functions in question:
func Login
https://github.com/pereztr5/cyboard/blob/master/cmd/newRoutes.go#L50

func RequireLogin
https://github.com/pereztr5/cyboard/blob/master/cmd/middleware.go#L74

func CheckCreds
https://github.com/pereztr5/cyboard/blob/master/cmd/webHandler.go#L24

I know I am not saving the sessions correctly because when looking at the header information I do not see any cookies set with the team IDs.

invalid key size

When I create new cookie store and do like:

var store = sessions.NewCookieStore(securecookie.GenerateRandomKey(1), securecookie.GenerateRandomKey(2))

I've got the the error message
crypto/aes: invalid key size 2

Why what do I wrong?

API enhancement to make it easier to defend against session fixation attacks

I believe the session API could be improved to make defending against session fixation attacks easier. It is currently possible to regenerate the session ID but it is a convoluted process that could really benefit from being documented and part of the API:

// NOTE: session is already opened from a FileSystemSore, error 
// checking is left out for brevity.

// First save the session data to use in our new regenerated session
sessiondata = session.Values

// Next destroy the current session (or at least make it empty)
session.Values = make(map[interface{}]interface{})
session.Save() 

// Restore the session data and make sure it gets a brand new ID 
session.ID = ""
session.Values = sessiondata
session.Save()

Since session fixation attacks do not make sense against CookieStore sessions I'm not sure if it should go in the Session API or in the Store API. However, since it applies to (almost) every other store I would probably opt for the Session API.

I am willing to tackle this issue but I would like to discuss what the API should look like before I go ahead.

Provide some support for loading all sessions?

So I know that this is not really generalizable over sessions as a whole, but it would be nice if sessions supported some notion of loading all existing user sessions. In particular, it wouldn't work for the cookie store, but most other stores, including FilesystemStore and anything backed by a database, should be able to implement it easily.

My primary use case is to facilitate killing all sessions for a given user except one. I'm working on a website where it's desirable to have a relatively lax security policy regarding session cookies, but occasionally, users will use the site from a different computer (e.g. in a computer lab), and if they're in a rush, will leave without logging out. When they later get back to their own computer, they should be able to tell the site that any other sessions for their user should be terminated.

I successfully implemented this in my store (a vendored copy of postgrestore), but it doesn't make sense to me to submit a PR to that particular Store implementation without having some support for it in sessions.

I understand that asking the store to load all sessions is a potentially expensive operation, but the idea is that it would only be used when some global operation on sessions needs to happen, which is very infrequently.

As far as how sessions would go about providing support for this operation, one backwards-compatible option would be to add a new interface:

// Name not set in stone, obviously.
type GetAllStore {
    Store
    GetAll() ([]*Session, error)
}

which could then be implemented by the Store implementations that are able to provide that call:

var store sessions.Store

// ...

if x, ok := store.(sessions.GetAllStore); ok {
    allSessions, err := x.GetAll()
} else {
    // not supported
}

Then users could iterate over allSessions and take any actions that they see fit based on its values. Updating a session this way would be potentially race-y, but again, my use case is just to delete them.

Thoughts?

Invalidating Other Sessions (no concurrent logged-in users)

First off, a thanks is in order - gorilla/sessions has excellent documentation and very helpful examples on the website. Thank you!

One seemingly common use-case that is not covered in the docs is the scenario of when a user logs in, all other sessions from that user should be invalidated. How is this supposed to be tacked using gorilla/sessions?

Here's a code snippet to illustrate the problem:

func loginHandler(w http.ResponseWriter, r *http.Request) {
    // Get the POSTed credentials
    // [omitted, just going to hardcode a username for now]
    username := "Fred"

    // Check the database to see if it is a valid login
    // [omitted, we checked the credentials and it passed, so we can proceed]

    // Establish a session cookie using gorilla/sessions
    session, _ := sessionStore.Get(r, sessionName)
    session.Values["logged_in"] = true
    session.Values["username"] = username
    session.Save(r, w)

    // Set "logged_in" equal to false for all other sessions with a username of username
    // [?????]
}

After some searching around, I did find the following GitHub issue that tangentially discusses this: #67

However, I wasn't able to completely follow the discussion, as it implies that the programmer should create a custom Store implementation, and I'm fairly new to Golang.

Apart from this, one possible way that I thought of to solve this problem is to use the michaeljs1990/sqlitestore implementation of gorilla/sessions. Then, I could just iterate over the sessions in the table and manually mess with the session values for any row that matched the username. However, this seems a bit hacky, and I wonder if it is the "wrong" solution.

Thanks again for reading.

Cookie flashes live forever

I expected that flashes would disappear at the next request, but that's definitely not the case.

Run this code, go to the index page and click the link several times. Try refreshing the page. All the flashes are still there.

`Save(r, w)` vs `Save(w, r)`

Functions in the standard library dealing with HTTP order arguments in the opposite way of sessions's Save method. For example, it is net/http.Redirect(w, r, ...) and ServeHTTP(w, r), whereas the various Save functions use Save(r, w).

This isn't something that can be fixed in this version of the package, but please consider swapping the arguments around in a future version.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.