Git Product home page Git Product logo

Comments (9)

jpfluger avatar jpfluger commented on May 27, 2024 2

I have my code all tested. Unfortunately I could not interface the new (or old) scs with Echo cleanly. I really like the clear design of the new scs and really like echo (much of my code-base uses echo already). The gorilla/sessions version of middleware doesn't meet my needs either.

I have a working version of an echo-enabled scs repository as a fork.

I don't mind keeping the fork current with scs changes but there isn't a way to post echo-related issues there. The way echo handles redirects/header writing and context saving were the "difficult" (impossible?) points of integration. I tried with an interface but... it just diverges too much.

Thoughts? I don't want to create confusion with the fork but I also think it would be helpful to echo-users. I could write a GIST... or could rename the repo to (scs-echo) and have echo-users post issues there.

from scs.

alexedwards avatar alexedwards commented on May 27, 2024 1

Thanks Jaret!

My main objectives for this were decoupling the modification and saving of session data, and making it easier for developers to communicate the session token to clients not using a cookie if they want to.

There's still a bit of work to do, I still need to port some of the stores (boltstore, dynamostore etc) from the old version and improve the documentation, but I'm happy with the new API : )

from scs.

razorness avatar razorness commented on May 27, 2024 1

Hi,

just tested this package with echo v4.1.17: it looks like it works.

Accessing session data works, writing session data works, renew token works and the cookie expiration gets updated.

Here is a code example with redis:

var SessionManager *scs.SessionManager

func Session() echo.MiddlewareFunc {
	pool := &redis.Pool{
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", viper.GetString(config.RedisHost))
		},
		MaxIdle: viper.GetInt(config.RedisMaxIdleConnections),
	}

	SessionManager = scs.New()
	SessionManager.Store = redisstore.New(pool)

	return echo.WrapMiddleware(SessionManager.LoadAndSave)
}

Accessing and writing session data works like this (another middleware):

func AuthMiddleware() echo.MiddlewareFunc {
	return func(h echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {

			userId := SessionManager.GetString(c.Request().Context(), "userId")
			// do some stuff 

		}
	}
}

To be honest, I didn't test it very well yet.

from scs.

szqmtl avatar szqmtl commented on May 27, 2024 1

I am kind of locate the problem which'd be in the function func (bw *bufferedResponseWriter) WriteHeader(code int).

The following snippet is the test function:

type bufferedResponseWriter struct {
	http.ResponseWriter
	buf         bytes.Buffer
	code        int
	wroteHeader bool
}

func (bw *bufferedResponseWriter) Write(b []byte) (int, error) {
	return bw.buf.Write(b)
}

func (bw *bufferedResponseWriter) WriteHeader(code int) {
	if !bw.wroteHeader {
		bw.code = code
		bw.wroteHeader = true
	}
}

func testLoadAndSave(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("in test load")

		bw := &bufferedResponseWriter{ResponseWriter: w}
		next.ServeHTTP(bw, r)
		fmt.Println("out test load")
	})
}

When I added the function to e.Use(echo.WrapMiddleware(testLoadAndSave)), the problem was reproduced. If I changed the code to

type bufferedResponseWriter struct {
	http.ResponseWriter
	buf         bytes.Buffer
	code        int
	wroteHeader bool
	W           http.ResponseWriter  // Keeping the original writer
}

func (bw *bufferedResponseWriter) Write(b []byte) (int, error) {
	return bw.buf.Write(b)
}

func (bw *bufferedResponseWriter) WriteHeader(code int) {
        bw.W.WriteHeader(code)        // execute the original writer
	if !bw.wroteHeader {
		bw.code = code
		bw.wroteHeader = true
	}
	
}

func testLoadAndSave(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("in test load")

		bw := &bufferedResponseWriter{ResponseWriter: w, W: w}.    // make a copy of original writer
		next.ServeHTTP(bw, r)
		fmt.Println("out test load")
	})
}

The problem was gone. Therefore, if someone could investigate further, the reason might be found and got it solved.

Thank you

from scs.

alexedwards avatar alexedwards commented on May 27, 2024

Sorry for the delay on this.

It's not obvious what to do about Echo. I'm pretty certain that the 'fault' (if there's such a thing) for the incompatibility issues lies with the design of Echo, not the design of SCS. SCS doesn't do anything unconventional, it works with the standard library, and I don't know of any other Go routers or frameworks where there is a compatibility problem.

A couple of years ago I spent some time trying to figure out exactly what was causing the problems with Echo. IIRC, I filed an issue for one bug I found, but even when that was fixed the problems continued. I think it has all got something to do with the way that Echo manipulates the request Context field. But I was never able to get to the bottom of it.

If it is possible to create a fork of SCS which works with Echo, called scs-echo then that would be great and I'm all for you (or anyone else) to do it 👍

from scs.

alexedwards avatar alexedwards commented on May 27, 2024

Thanks for the discussion about this. I don't think there is currently any specific action that needs to be taken on the main SCS respository, so I'm going to close it for now. Feel free to reopen if necessary.

from scs.

alexedwards avatar alexedwards commented on May 27, 2024

@razorness Thanks, that's interesting. I've updated the note on Echo compatibility in the README to be less strongly-worded for now:

You may have some problems using this package with the Echo framework. If you do, then please consider using the Echo session manager instead.

from scs.

razorness avatar razorness commented on May 27, 2024

I also tried to get scs working with gin-gonic. Because of the implementation of ResponseWriter and instantly sending of the headers in gin, scs is not working properly with gin-gonic.
However, echo and scs seems to be a great combination. 😎

from scs.

szqmtl avatar szqmtl commented on May 27, 2024

I tried echo 4.2 with scs 2.4, error hander didn't work. Both default error handler and custom error handler returned 200 although http.StatusBadRequest was specified in ctx.JSON. When I commented out the middle ware usage with scs, it worked again.

from scs.

Related Issues (20)

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.