Open thomasvvugt opened 4 years ago
You can look at the authboss client state, which is an implementation of the SessionState
and CookieState
storage configuration objects using the Gorilla Securecookie and Sessions packages. That repo should be a good starting point for your development.
Hi @ibraheemdev and thanks for pointing me to the authboss client state repo.
I have looked at these implementations for the SessionState
and CookieState
, where both objects use the ClientStateReadWriter
interface.
This interface ensures both objects are reading and writing states using the following structure;
ReadState(*http.Request) (ClientState, error)
WriteState(http.ResponseWriter, ClientState, []ClientStateEvent) error
Which takes the default http
Request and Response package.Is there a possibility to i.e. port Fiber's Ctx or FastHTTP's Context object to be able to comply to the ClientStateReadWriter
interface?
Fiber has an adaptor middleware to convert it's Ctx to an http.Handler
type, however I cannot seem to find an example on how to use custom packages instead of the http
package to use authboss in a different framework.
Thanks for the help!
I'm not familiar with Fiber or FastHTTP context, but it should be as simple as creating wrapper functions to satisfy the ClientStateReadWriter
Interface. I'll try to look into it when I have the time.
@thomasvvugt did you find a solution for this?
Hi @frederikhors, unfortunately not.
AuthBoss's implementation for the ClientStateReadWriter
takes an http.Request
and http.ResponseWriter
to to create a cookie storer. Custom implementations like Fasthttp or Fiber really require a different interface since they use their own Context handling.
@thomasvvugt Have you looked into fasthttpadaptor
? It allows you to convert net/http requests to fasthttp (fiber) requests. Something like this:
import (
"github.com/gofiber/fiber"
"github.com/valyala/fasthttp/fasthttpadaptor"
"net/http"
)
...
g.Get("/", WrapHandler(pprof.Index))
func WrapHandler(f func(http.ResponseWriter, *http.Request)) func(ctx *fiber.Ctx) {
return func(ctx *fiber.Ctx) {
fasthttpadaptor.NewFastHTTPHandler(http.HandlerFunc(f))(ctx.Fasthttp)
}
}
code block originally from this issue
Edit: You should probably use gofiber/adaptor
, which is a convenience layer on top of fasthttpadaptor
.
@ibraheemdev I tried very hard, but I can't figure out how to do.
This is LoadClientStateMiddleware
:
func (a *Authboss) LoadClientStateMiddleware(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
writer := a.NewResponse(w)
request, err := a.LoadClientState(writer, r)
if err != nil {
logger := a.RequestLogger(r)
logger.Errorf("failed to load client state %+v", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
h.ServeHTTP(writer, request)
})
}
This is was I also tried:
app := fiber.New()
app.Use(WrapHandler(authboss.LoadClientStateMiddleware))
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})
_ = app.Listen(":3000")
}
func WrapHandler(f func(http.Handler) http.Handler) func(ctx *fiber.Ctx) {
return func(ctx *fiber.Ctx) {
//fasthttpadaptor.NewFastHTTPHandler(http.HandlerFunc(f))(ctx.Fasthttp)
adaptor.HTTPHandlerFunc(http.HandlerFunc(f))(ctx)
}
But this is simply wrong.
Well, this seems to work:
func main() {
// New fiber app
app := fiber.New()
app.Get("/ping", adaptor.HTTPHandler(logMiddleware(adaptor.FiberHandler(ping))))
// Listen on port 3000
app.Listen(":3000")
}
func ping(c *fiber.Ctx) error {
return c.SendString("pong")
}
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
println("logging...")
next.ServeHTTP(w, r)
})
}
func greet(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello World!")
}
So, I'm sure it's possible. It'll just take some fiddling with.
Oh wow. Thanks for your commitment.
Your code works.
But what I don't understand is how to use LoadClientStateMiddleware
with app.Use()
.
As stated in Authboss docs, LoadClientStateMiddleware
needs to wrap each route (is a middleware) so i cannot use exaclty this example because logMiddleware
is called with adaptor.FiberHandler(ping)
in it.
What we need is something like:
app := fiber.New()
app.Use(adaptor.HTTPHandlerORSOMETHINGIDONTUNDERSTAND(initializedAuthboss.LoadClientStateMiddleware))
app.Get("/ping", ping)
app.Listen(":3000")
This is the problem.
Thanks again.
Using the below code I get this error:
panic: use: invalid handler func(http.Handler) http.Handler
func main() {
app := fiber.New()
app.Use(logMiddleware)
app.Get("/ping", ping)
_ = app.Listen(":3000")
}
func ping(c *fiber.Ctx) error {
return c.SendString("pong")
}
func logMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
println("logging...")
next.ServeHTTP(w, r)
})
}
I'm not really familiar with fiber and fasthttp. I opened up an issue there (gofiber/fiber#943), hopefully they can help you out
Thanks to @arsmn we can make it work now: https://github.com/gofiber/adaptor/issues/27#issuecomment-717486233.
Two remaining issues:
LoadClientStateMiddleware
sets context value which does not transfer to Fiber handler; can you help us with this, @aarondl?
how to transform this code mux.Mount("/auth", http.StripPrefix("/auth", ab.Config.Core.Router))
for Fiber; this code comes from here: https://github.com/volatiletech/authboss-sample/blob/master/blog.go#L274.
I'm trying with this code which compiles:
func main() {
ab := SetupAuthboss()
app := fiber.New()
app.Use(adaptor.HTTPMiddleware(ab.LoadClientStateMiddleware), remember.Middleware(ab))
app.Group("/auth", adaptor.HTTPHandler(http.StripPrefix("/auth", ab.Config.Core.Router)))
_ = app.Listen(":3000")
}
but crashes at runtime:
panic: use: invalid handler func(http.Handler) http.Handler
goroutine 1 [running]:
github.com/gofiber/fiber/v2.(*App).Use(0xc00011b200, 0xc00010ff58, 0x2, 0x2, 0x1, 0xbdcd94)
C:/go/pkg/mod/github.com/gofiber/fiber/v2@v2.1.1/app.go:391 +0x2d7
main.main()
C:/projects/go/fiberAndAuthboss/main.go:18 +0x129
exit status 2
Hi @frederikhors. Not sure I can help out here. Never used fiber before.
Was there any progress on this? I'm looking into how to integrate authboss natively in GoFiber. Biggest program is the lack of fasthttp support.
While the adaptor middleware should work, it does introduce overhead.
Hi all,
I am trying to combine authboss into a popular upcoming Go web-framework, Fiber and GORM to improve my current authentication implementation.
Fiber was built with FastHTTP as its core component with the ease-of-use and API-compatibility in mind of express. Fiber has it's own session package, based on FastHTTP's session package. Also, Fiber has developed methods to set and retrieve cookie values.
However, when creating the required
SessionState
andCookieState
storage configuration objects, I figured theClientStateReadWriter
interface only allows Reading and Writing the defaulthttp
Request and Response package; https://github.com/volatiletech/authboss/blob/master/client_state.go#L79I would love to implement Fiber's official session middleware and cookie methods to use authboss for authentication, but I have no clue on where to start regarding the implementation of the
SessionState
andCookieState
or maybe I am even the purpose of theMiddleware2()
method. I have started development for this implementation on the develop branch of my personal repo.Would you be able to give me a better approach into creating a flawless integration for the authboss package, using Fiber's
Ctx
(Context) object and it's session middleware? Thanks so much in advance, I would really love to collaborate on this further!