Giter Club home page Giter Club logo

redistore's Introduction

redistore

GoDoc Build Status

A session store backend for gorilla/sessions - src.

Requirements

Depends on the Redigo Redis library.

Installation

go get gopkg.in/boj/redistore.v1

Documentation

Available on godoc.org.

See http://www.gorillatoolkit.org/pkg/sessions for full documentation on underlying interface.

Example

// Fetch new store.
store, err := NewRediStore(10, "tcp", ":6379", "", []byte("secret-key"))
if err != nil {
	panic(err)
}
defer store.Close()

// Get a session.
session, err = store.Get(req, "session-key")
if err != nil {
	log.Error(err.Error())
}

// Add a value.
session.Values["foo"] = "bar"

// Save.
if err = sessions.Save(req, rsp); err != nil {
	t.Fatalf("Error saving session: %v", err)
}

// Delete session.
session.Options.MaxAge = -1
if err = sessions.Save(req, rsp); err != nil {
	t.Fatalf("Error saving session: %v", err)
}

// Change session storage configuration for MaxAge = 10 days.
store.SetMaxAge(10 * 24 * 3600)

redistore's People

Contributors

andrewgleave avatar antihax avatar boj avatar daisuke310vvv avatar dbellinghoven avatar deepzz0 avatar dougrad avatar elithrar avatar grimthereaper avatar justinmayhew avatar kisielk avatar philboltt avatar tsenart 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

redistore's Issues

gob: decoding into local type *string, received remote type map[interface]interface

I've hit a wall with this error after attempting to load a key from the session. I'm using gin-contrib/sessions which "thinly" wraps around redistore and gorilla/sessions. I create the Redis Store using a pre-existing pool and then utilize the session when handling authentication:

session.Set("AUTH_STATE", state)
session.Save()

In an OAuth callback handler I attempt to load the AUTH_STATE from the session (source):

v := session.Get("AUTH_STATE")
if v == nil {
  c.Error(errAuth.WithDetail("Auth state is nil"))
  c.Abort()
  return
}

The value is always nil. Though it seems the error occurs whenever the session is attempts to load at the beginning of every handler after the session is created.

I noticed @boj encountered this error while creating this project, but has since resolved the problem.

I've been banging my head on the table for days over this. I'd greatly appreciate any assistance.

securecookie: the value is not valid

securecookie: the value is not valid

store, err := redistore.NewRediStore(10000, "tcp", ":6379", "", []byte("AdsdsddsdBCDEFG")) if err != nil { panic(err) } defer store.Close() store.SetMaxAge(10 * 24 * 3600)

But the follow code is work:
store, err := redistore.NewRediStore(10000, "tcp", ":6379", "", []byte("ABCDEFG"))
IF it is not equal "ABCDEFG",it will occur the error above.

Session Size Limitation

I'm currently using gorilla/sessions and boj/redistore to temporarily save form data—I have two-step form (fill it in, preview it) and I'm saving the form data to the session to allow a user to go back and edit it. I was originally using the CookieStore, however it's pretty easy for a reasonably sized text-field to hit the 4K cookie size limit.

I switched the store over to RediStore, but am still hitting the same problem.

The functions securecookie.Encode & securecookie.Decode in gorilla/securecookie appear to check the length of a session during encoding/decoding (good!) but maxLength is fixed to 4096 bytes regardless of the actual store used.

Just in case it's user error, I'm setting the store up with the below. cookie isn't actually a cookie—I've just changed the store over and haven't done a search-replace yet!

var cookie *redistore.RediStore

func init() {

        // Register structs with encoding/gob to allow gorilla/sessions to serialise.
    gob.Register(&Listing{})

        cookie = redistore.NewRediStore(10, "tcp", ":6379", "", authKey)

    // TODO(matt): Secure set to "false" for development.
    cookie.Options = &sessions.Options{
        Path:     "/",
        Domain:   "dr-jones.local",
        MaxAge:   3600 * 4,
        Secure:   false,
        HttpOnly: true,
    }
}

... and saving my form by decoding r.PostForm into a Listing struct with gorilla/schema.

session, err := cookie.Get(r, "demo")
listing := &Listing{}

err = decoder.Decode(listing, r.PostForm)
session.Values["listing"] = listing

err = session.Save(r, w)

I get the error on session.Save() and session.Values["listing"] when decoding it.

PS: I've removed the errors handling stuff here—but I check for all of them. I've got some extra debug stuff in there now that's helped me track this down.

NewRedisStore Behaviour

I'm curious about the behaviour of NewRediStore in https://github.com/boj/redistore/blob/master/redistore.go#L67

Specifically, the error returned from redis.Dial does not seem to be propagated out when creating the store. Am I correct in assuming this, and if so, is there a way to resolve it either in my own code and/or in a way that doesn't break backwards compat?

func NewRediStore(size int, network, address, password string, keyPairs ...[]byte) *RediStore {
        rs := newRediStore(size, network, address, password, keyPairs)
        rs.Pool.Dial = func() (redis.Conn, error) {
                c, err := redis.Dial(network, address)
                if err != nil {
                        return nil, err
                }
                if password != "" {
                        if _, err := c.Do("AUTH", password); err != nil {
                                c.Close()
                                return nil, err
                        }
                }
                return c, err
        }
        return rs
}

Race condition in Redistore

There is a race condition in RediStore. The same issue is also present in FilesystemStore at gorilla/sessions#10. I am currently waiting for input from Gorilla maintainer because fixing this would introduce subtle differences to the API. In the mean time I wanted to let you know about this issue.

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 written a test case for the flaw in FilesystemStore at cless/sessions@f84abed in case you would like to see some code to reproduce the issue.

Secure

You save token in redis, like this:
session_MTU0NzU3NjI4OXxLb19wWWFhVS1GOHBqV0FZNENLSlN3eDNwbWd2bF84RTBhY016ZmF3NENkWE5TbGtXODJxUm5DS1Nkdk9oRDBZb1NmaXZUSGhmUDA1cU9FUkhBaE94M3JUZkZXQTNaaFp81l5Qc3IXE-ItbYJwVAycl7007V5yiDg48Q6AKTwHk6Q=

I think it's not secure:

And just to reiterate one of the most common pitfalls, DO NOT STORE THE PERSISTENT LOGIN COOKIE (TOKEN) IN YOUR DATABASE, ONLY A HASH OF IT! The login token is Password Equivalent, so if an attacker got their hands on your database, they could use the tokens to log in to any account, just as if they were cleartext login-password combinations. Therefore, use hashing (according to https://security.stackexchange.com/a/63438/5002 a weak hash will do just fine for this purpose) when storing persistent login tokens.

https://stackoverflow.com/questions/549/the-definitive-guide-to-form-based-website-authentication#477579

Please update redigo

go: warning: github.com/gomodule/[email protected]+incompatible: retracted by module author: Old developmentd or published.
go: to switch to the latest unretracted version, run:
        go get github.com/gomodule/redigo@latest

Propagate `gob/encoding` errors.

I was getting an error in my code that I only discovered after debugging this line. The error here was: gob: name not registered for interface: ....

I understand that it is my issue that I did not register my type with gob at the time that I tried to access the value in the session, but it was not intuitive and there was no error thrown in my face.

We can close the issue if we determine that I am sufficiently bad at this.

Support vgo/go.mod & Tag New Release

To support upcoming versioning support in the Go toolchain (beta in 1.11, prod in 1.12) -

  • Add a go.mod file to this repo
  • Tag a new release (likely v1.2.1 after I review the changes)
  • Update Build Status in README to use Travis

Get: base64 decode failed

I'm getting the error securecookie: base64 decode failed - caused by: illegal base64 data at input byte 40 when running the following code:

store, _ := redistore.NewRediStore(10, "tcp", ":6379", "", []byte("secret-key"))
sess, err := store.Get(r, "session-key")
if err != nil {
  panic(err)
}

However, if I remove the error checking, everything works fine and the session gets created correctly in Redis. The same seems to happen for store.New(r, "session-key").

I'm using Redis 4.0.1.

Enhancement request to extend session automatically during use

As I understand, with the current implementation irrespective of usage, the session times out at a set time. Similar to Java based session implementation, would it be possible to extend the expiration of session during continuous use? I hope this is the right way to request an enhancement request.

custom structs missing from GOB will silently fail and return sessions without some values.

The error from s.load(session) is out of scope of the return and will silently fail to deserialize custom structs missing from gob and stored in values.

Replication:

  1. gob.Register(oauth2.Token{})
  2. save an oauth2.Token{} structure to a session.Values
  3. remove gob.Register(oauth2.Token{})
  4. Attempt to read the value again. Valid session returned, no error given, and values beyond are not deserialized.
// New returns a session for the given name without adding it to the registry.
//
// See gorilla/sessions FilesystemStore.New().
func (s *RediStore) New(r *http.Request, name string) (*sessions.Session, error) {
	var err error

	session := sessions.NewSession(s, name)
	// make a copy
	options := *s.Options
	session.Options = &options
	session.IsNew = true
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.Codecs...)
		if err == nil {
			*ok, err := s.load(session)*
			session.IsNew = !(err == nil && ok) // not new if no error and data available
		}
	}
	return session, err
}

Allow passthrough of `DialOptions`

The initial connect timeout is too slow for us, so we'd like to be able to pass a connection timeout to the redis store. This should be pretty straight forward with redis.Dial which allows a DialOptions as a third parameter which can be used to specify the connection timeout in addition to some other goodies.

Update TravisCI config to use Redis & Add Mocks

Tests should be able to run, in part, without a running Redis instance via mocks.

  • Support configuration of Redis address for tests via env vars
  • Configure Travis to install Redis into the container & run tests against it
  • Split tests into separate functions (unit tests vs. integration tests)
  • Make integration tests optional / skippable when Redis not available via the -short flag.

Delete all sessions by user

So, I want to give my users the ability to sign out of all other devices. Is that something I could do with this software, or would I need to make my own solution?

Ping

Right now every get or set pings the redis server first. This adds some latency to it. Any reason for this?

Problem with session (MaxAge == 0) cookie

The change made in this commit appears to cause issues when trying to create session (non-durable) cookies. So now, when trying to set MaxAge = 0 (so that the cookie is session-only and doesn't live on), then it's instead deleted, and then set with an empty value. The result is an inability to have a session without having a persisted cookie.

NOTE: We use echo sessions in our project, which through dependencies, uses redistore. Some work-around was followed to pin go dep to use the master branch of redistore, rather than an older version.

Wrong number of arguments for SET on Save

When trying to save, using redistore.Save(request, writer, session). A "Wrong number of arguments for 'set' command"

This is caused by the redis command used to save, currently you use SET key value EX ttl

However you should do SETEX key ttl value

drone.io Badge Fix

The drone.io link is no longer valid. Can we get this fixed so that we have an idea of whether the project is currently building?

Session synchronization problem

Session saved in cookie and redis, why delete the data in the cookie , session is invalid? Should not be read from the redis?

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.