Git Product home page Git Product logo

scs's People

Contributors

alexedwards avatar alinnert avatar bishopofturkey avatar bramvbilsen avatar cgossain avatar daniel-sogbey avatar decafe09 avatar dependabot[bot] avatar fnoopv avatar gandaldf avatar gernest avatar hycner avatar joesonw avatar jum avatar lafriks avatar makslevental avatar mvrhov avatar nevernotmove avatar pangaunn avatar royallthefourth avatar sh4nks avatar slinso avatar srenatus avatar stereosteve avatar stillwondering avatar testwill avatar verygoodsoftwarenotvirus avatar xuo avatar zaeph avatar zchenyu 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

scs's Issues

Use Redis to store idle timeout issues

This is my code snippet, I use Redis storage, and define the IdleTimeout value is 20 minutes and the Lifetime value is 2 hours, but the session data is always in 20 minutes of failure, the page refreshes does not seem to automatically extend the idle timeout time?

SessionManager = scs.NewManager(
	redisstore.New(&redis.Pool{
		MaxIdle: 10,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", "127.0.0.1:6379", redis.DialDatabase(0))
		},
		IdleTimeout: time.Duration(20) * time.Minute,
	}),
)
SessionManager.IdleTimeout(20 * time.Minute)
SessionManager.Lifetime(time.Duration(2 * time.Hour)

Provide example of using SCS with Echo

Should scs include a folder dedicated to middleware examples? It would be similar to stores but dedicated to middleware for scs.

Or would it be better for scs to make reference to third party middleware implementers on its README?

It's a classic question. Either direction works for me primarily b/c scs doesn't have many open issues. If scs was highly trafficked in terms of issues, I'd probably suggest breaking-out the middleware to third parties.

I have some echo middleware to contribute - just let me know what you'd prefer. Others may find a landing spot for their ideas too. (see #16)

Re-add Token() for v2

My middleware unit testing used the v1 Token() function for verifications of client-server responses. Does v2 have a way for middleware to access the private token directly?

go get github.com/alexedwards/scs/v2 fails

go get github.com/alexedwards/scs/v2
package github.com/alexedwards/scs/v2: cannot find package "github.com/alexedwards/scs/v2" in any of:
/usr/local/go/src/github.com/alexedwards/scs/v2 (from $GOROOT)
/home/wise/go/src/github.com/alexedwards/scs/v2 (from $GOPATH)

I'm moving a site I have in development to a new machine. I have the site working on another machine, I last set that one up maybe a week ago.

What's the easiest way to use scs and postgresql?

Compatibility issues with the Echo framework

I use the scs/session package in Echo, and if I export anything to the browser in the HTTPErrorHandler function of Echo, the Echo of logger will print such warning messages:
Level:WARN, file:context.go, line:484, message:response, already, committed.
If I don't use session, there won't be such a problem.

package main

import (
	"time"

	"github.com/alexedwards/scs/engine/memstore"
	"github.com/alexedwards/scs/session"
	"github.com/labstack/echo"
)

func main() {
	app := echo.New()
	app.Debug = true
	sessionManager := session.Manage(memstore.New(12 * time.Hour))
	app.Use(echo.WrapMiddleware(sessionManager))
	app.HTTPErrorHandler = errorHandler
	app.Start(":80")
}

func errorHandler(err error, ctx echo.Context) {
	ctx.String(200, "test")
}

Changing a session timeout period

Hi,
Is it possible to change the session's expiry on a single session basis? I need some of my users to have much longer sessions than others, but it seems the session.IdleTimeout call has a global affect. Am I missing something?

Cheers,
Shmul

Echo compatibility

Well done @alexedwards on re-imagining scs. ๐Ÿฅ‡ This was a comprehensive rewrite. A number of items I appreciate:

  • Status
  • Efficient load/save with help from Status
  • Session and SessionCookie are global in scope
  • I also like that IdleTimeout and Lifetime were split from the old options.
  • go.mod added for go modules support

For me, v2 solves a number of issues for which I had kept a permanent local fork of scs on my machine. (My fork was getting a bit dated too!)

I've done some testing and so far so good. I had one issue with a private token but this example provides a powerful solution to my issue.

ERROR illegal base64 data at input byte 5

I tried to use scs with echo on very simple application, but I get this error. I use session.PutObject to store the data, and session.GetObject to read the data.

package main

import (
	"github.com/alexedwards/scs"
	"github.com/labstack/echo"
	"net/http"
)

var sessionManager = scs.NewCookieManager("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4")

type UserModel struct {
	ID   string
	Name string
	Age  int
}

func main() {
	const SESSION_ID = "id"

	e := echo.New()

	e.HTTPErrorHandler = func(err error, c echo.Context) {
		report, ok := err.(*echo.HTTPError)
		if !ok {
			report = echo.NewHTTPError(http.StatusInternalServerError, err.Error())
		}

		c.Logger().Error(report)
		c.JSON(report.Code, report)
	}

	e.Use(echo.WrapMiddleware(sessionManager.Use))

	e.GET("/index", func(c echo.Context) error {
		session := sessionManager.Load(c.Request())

		user := new(UserModel)
		user.ID = "001"
		user.Name = "Noval"
		user.Age = 12

		err := session.PutObject(c.Response(), SESSION_ID, *user)
		if err != nil {
			return err
		}

		return c.Redirect(http.StatusTemporaryRedirect, "/home")
	})

	e.GET("/home", func(c echo.Context) error {
		session := sessionManager.Load(c.Request())

		user := new(UserModel)
		err := session.GetObject(SESSION_ID, user)
		if err != nil {
			return err
		}

		return c.JSON(http.StatusOK, user)
	})

	e.Logger.Fatal(e.Start(":9000"))
}

The error occur on the part where the session is being read.

{"Code":500,"Message":"illegal base64 data at input byte 5","Internal":null}

Provide a must have session middleware

Hi,

Firstly, thank you for this package, I've been rolling my own similar one and in frustration Google again and found this project. This greatly simplifies session management for me, without requiring bring in a library or using an overly simple package like gorilla/sessions (nothing wrong with it, I just needed more).

One piece that I'd also like this to handle is the ability to redirect a user if a session doesn't exist (new user or expired session). For example, keeping sessions for all handlers, except a few that are for logged in users only.

I'm currently handling this with my own middleware successfully. If the user does not have the key username set in the session, they are redirected to /login.

func MustExist(next http.Handler) http.Handler {
     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
         if ok, _ := session.Exists(r, "username"); !ok {
             http.Redirect(w, r, "/login", http.StatusFound)
             return
         }
         next.ServeHTTP(w, r)
     })
 }

I'd love to know if there's a way to detect if there's a session at all, as in my case, and the common (but not all) cases, a user would just want to know that someone is logged in.

This isn't a lot of code to write, but it's also possible to get wrong, and I'd want to copy this exact signature across a few sites, so having this provided by the session package would be ideal.

To do this, I think it'd be best if it's just a check if the user has a valid session, but the problem I found was that an earlier handler detects the lack of session and added one. So this handler was never able to detect the lack of session. Is there a way to detect if a session doesn't currently exist for this user without adding storing keys?

Would it be possible to provide this middleware as part of the session package? I had a stab at an API:

  type MustExist struct {
      Key         string
      RedirectURL string
  }

  func (m *MustExist) Handler(next http.Handler) http.Handler {
      return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
          if ok, _ := session.Exists(r, m.Key); !ok {
              http.Redirect(w, r, m.RedirectURL, http.StatusFound)
              return
          }
          next.ServeHTTP(w, r)
      })
  }

And it could be used like:

&MustExist{Key: "username", RedirectURL: "/login"}.Handler

But this is still requiring a string key be set, and the API itself is quite ugly. As a user, I'd prefer to just use:

// MustHaveSession redirects a user to redirectURL if no session exists (or it's expired).
// No other handlers or middleware are executed.
func MustHaveSession(redirectURL string) func(http.Handler) http.Handler

Is this possible?

Can't load session multiple times in same request and get saved value

package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/alexedwards/scs"
)

var manager = scs.NewCookieManager("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4")

type Site struct {
}

func (site Site) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	session := manager.Load(req)
	session.PutString(w, "key", "value")
	fmt.Println(session.GetString("key"))

	session2 := manager.Load(req)
	// should be able to get saved value
	fmt.Println(session2.GetString("key"))
}

func main() {
	Server := httptest.NewServer(Site{})

	http.Get(Server.URL)
}

https://github.com/alexedwards/scs/blob/master/session.go#L41

Maybe should save session into request's context, and load it from context next time?

mysqlstore with MySQL < 5.6: UTC_TIMESTAMP(6) parameter unsupported

With MySQL before version 5.6, I get SQL errors in mysqlstore.go. They are caused by UTC_TIMESTAMP(6). The parameter was introduced in MySQL 5.6.4 (see the docs) and "is given to specify a fractional seconds precision from 0 to 6". In MySQL 5.6, they also changed the default format from 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu to 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.

I'm not sure if it a "MySQL version switch" in mysqlstore would be feasible. But is it necessary to store the expiry timestamp with such a precision at all? Would't one second be precise enough? Then we could omit the parameter of UTC_TIMESTAMP(6).

Add support for Touch Interval Rate

Looking for some feedback on whether or not this is a good idea. I'd like finer control of Touch(). Why? For a high-volume site, each Touch is a new update to deadline and therefore a new write to the data store. While some handlers will always uses sessions others will not, such as serving static files. Admittedly there are other ways to design this. For example in middleware, I could skip calling Touch for any path serving static files. But a few seconds delay in Touch would serve the same purpose. (And for those static files, I'm still updating global statistics - just not session stats on the static files - which I'm not tracking.)

What if there was a TouchIntervalRate to control how often the deadline gets updated via touch? It could manifest itself a few ways. Arguably the easiest is a new function, session.TouchWithInterval().

// in session.go
// TouchWithInterval func controls the rate at which touches are automatically written via Touch
// there can be quite a few quick touches - which mean writes back to the datastore
// would require a private "isNew" var added to manager.Session
func TouchWithInterval(w http.ResponseWriter, interval time.Duration) error {
	if s.loadErr != nil {
		return s.loadErr
	}

	doTouch := true
	if !s.isNew && interval > 0 {
		timeToTouch := time.Now().Subtract(s.deadline).Add(interval)
		doTouch = timeToTouch.Afer(time.Now())
	}

	if doTouch {
		return Touch(w)
	}

	return nil
}

Thoughts?

Using scs with Negroni

Due to the nature of the middleware returned from session.Manage(), I'm not seeing a way to chain this middleware with Negroni.

Is there a way to use the middleware provided by scs within negroni?

stale sessions in data store - `deadline` plus `saved` property?

How are folks handling stale sessions in the data store? For example, redis has its expire command but by default it is set to never expire.

If a vacuuming routine compares time.Now() > deadline, then the session should be deleted. That's the logic, yes?

Is there any use case for including a saved property (the date when a session was last saved) - in addition to the deadline? Right now I can't think of any. Maybe I just answered my own question but am double-checking with others.

Allow access to session through context

The session middleware populates the context with the session using a custom string type as a key. Thus it cannot be accessed from the outside without the *http.Request object through Manager.Load(req).

Would you accept a patch adding Manager.LoadFromContext(ctx) method so one can access the session in a scope where the request is not available but its context is?

The problem of log.Println() in Use() function

I use SCS as the session middleware in the Echo framework, but in the process of operating session, if the Redis service is closed, it triggers the log.Println() in the Use() function.
My Code is like this:
echo.Use(echo.WrapMiddleware(session.Use))
I hope this error triggers Echo's error and shouldn't print error messages directly on the server console.
How do I do that?

Error types leak through from storage systems

If I invoke a function like GetObject, it sometimes has a non-nil error that comes from the underlying storage system. In order to handle these gracefully, I'd need to program against the underlying storage system to handle something like "cache key not found". I'm specifically talking about the memcached backend here, but it looks like other storage systems use the same leaky abstraction. This defeats the abstraction offered by SCS since I can't easily handle errors generated by multiple backends in the same way. In short, my code that uses scs.Manager shouldn't need to know about memcache.ErrCacheMiss.

To fix this problem, I propose implementing new SCS error types that can map onto the most common storage backend errors in a sensible way:

ErrNotFound
ErrBackendFailure
ErrSomethingElse...

This would provide abstraction over the underlying errors without hiding too much about what's really happening. I'd be happy to program this myself and rework all of the storage backends to use it.

What do you think?

[discussion] consider cookieless sessons

For an API I needed to store the session-id somewhere else instead of the cookie header field. So I added the possibility to also use a string instead of an http.Request. Sadly it breaks the public API so I won't issue a pull request, but maybe someone else has a better idea making it work without breaking changes.

https://github.com/ChristophPech/scs

Separate modification and saving of session data

See discussion in #23

This could be addressed by implementing Middleware which uses a custom ResponseWriter to intercept HTTP Responses, save the session data to the store and set the session cookie - similar to v0.1 of SCS (https://github.com/alexedwards/scs/blob/v0.1.0/session/manager.go)

Downside is that this causes problems with frameworks/applications which also try to call WriteHeader. See #15

A workaround might be to set the session cookie header each time the session is modified (or even loaded) and only handle saving to the store in the middleware. I think that would work for most stores, except the CookieStore, which needs the response headers to not have already been written.

[help] Strange behavior

Sorry, i cant share the code right now. Just need some light for finding the issue. Sometimes the session just doesnt work and create many tokens for the same user (im using mysqlstore, so is easy to see this). Now session only works after calling RenewToken. Did this descriptions identify with any common misuse of the library? Ive already tried a lot of things. Thanks and sorry for the lack of more info.

This is a bug or my usage is wrong?

I use echo v3, I repeat the request controller (refresh page), it will create a number of records in redis scs / session, this is a bug or I use the wrong method?
the code is probably this:

main.go

engine := redisstore.New(
	&redis.Pool{
		MaxIdle: 10,
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", "127.0.0.1:6379")
		},
	},
)

sessionManager := session.Manage(
	engine,
	session.HttpOnly(true),
	session.IdleTimeout(20*time.Minute),
	session.Lifetime(3*time.Hour),
)
App.Use(echo.WrapMiddleware(sessionManager))

Controller

func Index(ctx echo.Context) error {
	data := make(map[string]interface{})
	session.PutString(ctx.Request(), "sess", "ok")
	data["sess"], _ = session.GetString(ctx.Request(), "sess")
	return ctx.Render(200, "index.jet", data)
}

Refresh three pages, redis appeared in three records, I think this is not normal?

1
2
3

Use securecookie

Any objection to using securecookie to write and load the session token/key/id from the cookie?

I think it's a good idea to use signed cookies to prevent tampering. e.g. you can avoid unnecessary queries to the session store by throwing away invalid cookies

With you blessing, I'll open a PR to integrate securecookie into scs with the following features:

  1. Backwards compatible with existing valid scs cookies. We could accomplish this with one of the following approaches:
    1. Flag to enable securecookies
      • Won't "upgrade" cookies in-place
    2. Pack/encode the cookie value differently - Would have to use a non-base64 encoding character to signify differences
      • Will upgrade cookies in-place
      • Could encode the cookie value as a JSON string or just use a simple non-base64 character
    3. Migrate to another cookie name
      • Will upgrade cookies in-place
      • Secure cookie name would be configurable e.g. add secureName field to options struct
      • I prefer this approach since it's a cleaner design and we can use the configurable string enable/disable securecookies e.g. empty string disables secure cookies
  2. Unit-tested

Getting token value in v2

Congratulations on v2.

Would you consider adding a function similar to Token() in v1 for fetching the token value? I have a problem to keep track on the latest login by session token because I cannot get the value after calling RenewToken. Maybe is there an alternative way?

it'd work for me in my case If adding this function in data.go, but only a thought.

func (s *Session) Token(ctx context.Context) string {
	sd := s.getSessionDataFromContext(ctx)
	return sd.token
}

Thanks for the library.

use of closed network connection

I use SCS to implement session functionality in the echo framework, but I delete the sessionid in cookie and then refresh the browser and output the error:

redigo: unexpected type for Bytes, got type []interface {}
redigo: unexpected response line (possible server error or unsupported concurrent read by application)
write tcp 127.0.0.1:49741->127.0.0.1:6379: use of closed network connection

My code:

//Connect Redis
func connectRedis() (redis.Conn, error) {
	conn, err := redis.Dial("tcp", "127.0.0.1:6379")
	if err != nil {
		return nil, err
	}
	return conn, err
}

//Configure SCS
func SetSession() error {
	redisConn, err := connectRedis()
	if err != nil {
		return err
	}
	redisPool := redisstore.New(redis.NewPool(func() (redis.Conn, error) {
		return redisConn, nil
	}, 1))

	SessionManager = scs.NewManager(redisPool)
	SessionManager.Name("sessionid")
	SessionManager.Path("/")
	SessionManager.Lifetime(60 * time.Minute)
	SessionManager.Secure(false)
	SessionManager.HttpOnly(true)
	SessionManager.IdleTimeout(20 * time.Minute)
	SessionManager.Persist(true)
	return nil
}

//Echo middleware
func SessionMiddleware() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(ctx echo.Context) error {
			//update session idletime
			session := SessionManager.Load(ctx.Request())
			err := session.Touch(ctx.Response().Writer)
			if err != nil {
				return err
			}
			return next(ctx)
		}
	}
}

Using scs with Echo

Is there a way to use the middle ware provided by scs within echo? I try to do as below way, but failed. Can you give me some suggestion?

package main

import (
    "github.com/labstack/echo"
    "github.com/labstack/echo/engine/standard"
    "github.com/labstack/echo/middleware"
    "github.com/alexedwards/scs/session"
    "github.com/alexedwards/scs/engine/memstore"
    "net/http"
)

func main() {
    sessionManager := session.Manage(memstore.New(0))
    e := echo.New()
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Use(standard.WrapMiddleware(sessionManager))
        e.SetDebug(true)

    e.GET("/", func(c echo.Context) error {
        err := session.PutString(c.Request().(*standard.Request).Request, "username", "admin")
        if err != nil {
            c.Logger().Error("session.PutString:", err)
            return err
        }

        if msg, err := session.GetString(c.Request().(*standard.Request).Request, "username"); err != nil || len(msg) == 0 {
            c.Logger().Info("session.GetString:", msg)
        }

        return c.String(http.StatusOK, "Hello, World!")
    })

    e.Run(standard.New(":1323"))
}

SessionManager scope

Can you please tell if SessionManager is global in scope meaning bootstrapped from some Init function

Multiple Set-Cookie headers in response

Here is small example:

package main

import (
	"net/http"

	"github.com/alexedwards/scs"
)

var sessionManager = scs.NewCookieManager("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4")

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("/auth", login)

	http.ListenAndServe(":4000", sessionManager.Use(mux))
}

func login(w http.ResponseWriter, r *http.Request) {
	session := sessionManager.Load(r)
        
        // authenticate user ...

	err := session.RenewToken(w)
	if err != nil {
		http.Error(w, err.Error(), 500)
                return
	}

	if err := session.PutInt(w, "userId", 1); err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	if err := session.PutBool(w, "isAdmin", true); err != nil {
		http.Error(w, err.Error(), 500)
		return
	}
}

Here is /auth response:

HTTP/1.1 200 OK
Set-Cookie: session=rXoTm-uiZM8eYszKWKTbUP-D-SBV0Pdx8DyMpX7jL55yVcOwRxLROJSeDHeuW0iYifwVpUnEiXyhU_H-Vl-1-2LpnjHnOvx1TS1yYuoccQP6P56iEXyCzngQRt_UkHGG5Wva5-0; Path=/; HttpOnly
Set-Cookie: session=6HjYzvYsALD_UvkBNlrheCKijlQDAAd2rMsWN_URq7uO12n2ng2t-7PYSmHSV8l3n0TKtb6_y0-DKuc--uikxCBJ-NuvR0a91vj7dauPu_TMrCGtfa1cOgLpr1R2MhTCDt4qUNwmBNEblJrViAiW; Path=/; HttpOnly
Set-Cookie: session=ewJmYE3psbCYtX39Zgj-Utv5XTjCJ5SfbsO32daXPyOovU0y0O2OPQtv6QlL9Zv-yZ-XJuYqPvkZQ5tt_tjLqtpKdvohTOLAjLp7XO9yfVjV5rgtC6hG5b9W0Hb_8shOUdZdKZdM936IEAbaRkltlDOEYqBSbFcXoZIjJUKs; Path=/; HttpOnly
Date: Thu, 26 Oct 2017 09:08:01 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

As you can see there are three different Set-Cookie headers with the same cookie-name in response which is wrong according to RFC 6265:

Servers SHOULD NOT include more than one Set-Cookie header field in
the same response with the same cookie-name.

[discussion] consider switching to bbolt backend

Ben Johnson, the creator of bolt, has declared his project as feature complete and won't provide further support due to lack of time (see boltdb/bolt@fa5367d).

CoreOS forked the project over to bbolt and pushes development of the project forward. Popular projects based on boltdb, like storm are already on the migration path to bbolt.

Having said that, bolt works great for me, and you've already moved your API to v1, so switching the bolt backend over to bbolt would probably break your v1 contract.

Just opening this issue to raise awareness to the change in bolt's future.

And thanks for this very fine project ๐Ÿ˜„

Add manager.Opts() method to expose option

Since Opts is not exposed, custom middleware extension is not possible, in case I want to write my own middleware.
Referring

scs/manager.go

Line 114 in 876a0fd

func (m *Manager) Use(next http.Handler) http.Handler {
, m.opts.Timeout cannot be accessed from outside package.

What if by adding manager.Opts() method, which returns opts.

Session doesn't work

Hi,
first thank you for this great package.
after some hours of trying to get it work, i decided to give a try the sample code
i use curl put get but hello world is not printed.

Improve storage to support exclusive locks

As I can see, the redis storage implementation doesn't support any locks.
There's no documentation on mechanism to how to do this right.
The current Store interface doesn't provide any locks interface even for custom implementations.

So, I'd really like to see this change so one could implement their own locks (until someone makes some library).

For example, there's only one implementation of locks I've found (a simple one):
https://github.com/bsm/redis-lock

scs: no session data in context

Abstract: Example code not working - resulting in stacktrace

Example used

At first, I suspected some issues with the filesystem (though /tmp should be writable).
But even if you substitute the bolt examplecode by the memstore example code, the app crashes.

Operating system:
Linux MYBOX 5.1.16-1-default #1 SMP Wed Jul 3 12:37:47 UTC 2019 (2af8a22) x86_64 x86_64 x86_64 GNU/Linux

Go Version: go version go1.12.6 linux/amd64

Ignoring paths

Is it possible to set a list of folders that the session manager needs to ignore? This is quite useful for static files.

New Release?

Hello - would it be possible to release a new version? I noticed that there is an unreleased change with the updated location of the redigo library.

Appreciate your efforts!

Memcached support?

Looking around for a new session manager, one which supports memcached.

SCS looks interesting and is written for modern Go (unlike Gorilla), but doesn't (yet) support memcached.

Any plans on memcached support? ๐Ÿ˜„

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.