mirror of
https://github.com/teamhanko/hanko.git
synced 2025-10-27 14:17:56 +08:00
feat(backend): let cookie name be configurable through config
This commit is contained in:
@ -216,12 +216,21 @@ type Password struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Cookie struct {
|
type Cookie struct {
|
||||||
|
Name string `yaml:"name" json:"name" koanf:"name"`
|
||||||
Domain string `yaml:"domain" json:"domain" koanf:"domain"`
|
Domain string `yaml:"domain" json:"domain" koanf:"domain"`
|
||||||
HttpOnly bool `yaml:"http_only" json:"http_only" koanf:"http_only" split_words:"true"`
|
HttpOnly bool `yaml:"http_only" json:"http_only" koanf:"http_only" split_words:"true"`
|
||||||
SameSite string `yaml:"same_site" json:"same_site" koanf:"same_site" split_words:"true"`
|
SameSite string `yaml:"same_site" json:"same_site" koanf:"same_site" split_words:"true"`
|
||||||
Secure bool `yaml:"secure" json:"secure" koanf:"secure"`
|
Secure bool `yaml:"secure" json:"secure" koanf:"secure"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cookie) GetName() string {
|
||||||
|
if c.Name != "" {
|
||||||
|
return c.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
return "hanko"
|
||||||
|
}
|
||||||
|
|
||||||
type ServerSettings struct {
|
type ServerSettings struct {
|
||||||
// The Address to listen on in the form of host:port
|
// The Address to listen on in the form of host:port
|
||||||
// See net.Dial for details of the address format.
|
// See net.Dial for details of the address format.
|
||||||
|
|||||||
@ -166,6 +166,13 @@ session:
|
|||||||
# Default value: true
|
# Default value: true
|
||||||
#
|
#
|
||||||
secure: true
|
secure: true
|
||||||
|
## name ##
|
||||||
|
#
|
||||||
|
# Sets the name of the cookie.
|
||||||
|
#
|
||||||
|
# Default value: hanko
|
||||||
|
#
|
||||||
|
name: true
|
||||||
## enable_auth_token_header ##
|
## enable_auth_token_header ##
|
||||||
#
|
#
|
||||||
# The JWT will be transmitted via the X-Auth-Token header. Enable during cross-domain operations.
|
# The JWT will be transmitted via the X-Auth-Token header. Enable during cross-domain operations.
|
||||||
|
|||||||
@ -59,6 +59,8 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
panic(fmt.Errorf("failed to create session generator: %w", err))
|
panic(fmt.Errorf("failed to create session generator: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sessionMiddleware := hankoMiddleware.Session(cfg, sessionManager)
|
||||||
|
|
||||||
mailer, err := mail.NewMailer(cfg.Passcode.Smtp)
|
mailer, err := mail.NewMailer(cfg.Passcode.Smtp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("failed to create mailer: %w", err))
|
panic(fmt.Errorf("failed to create mailer: %w", err))
|
||||||
@ -70,23 +72,23 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
passwordHandler := NewPasswordHandler(persister, sessionManager, cfg, auditLogger)
|
passwordHandler := NewPasswordHandler(persister, sessionManager, cfg, auditLogger)
|
||||||
|
|
||||||
password := e.Group("/password")
|
password := e.Group("/password")
|
||||||
password.PUT("", passwordHandler.Set, hankoMiddleware.Session(sessionManager))
|
password.PUT("", passwordHandler.Set, sessionMiddleware)
|
||||||
password.POST("/login", passwordHandler.Login)
|
password.POST("/login", passwordHandler.Login)
|
||||||
}
|
}
|
||||||
|
|
||||||
userHandler := NewUserHandler(cfg, persister, sessionManager, auditLogger)
|
userHandler := NewUserHandler(cfg, persister, sessionManager, auditLogger)
|
||||||
|
|
||||||
e.GET("/me", userHandler.Me, hankoMiddleware.Session(sessionManager))
|
e.GET("/me", userHandler.Me, sessionMiddleware)
|
||||||
|
|
||||||
user := e.Group("/users")
|
user := e.Group("/users")
|
||||||
user.POST("", userHandler.Create)
|
user.POST("", userHandler.Create)
|
||||||
user.GET("/:id", userHandler.Get, hankoMiddleware.Session(sessionManager))
|
user.GET("/:id", userHandler.Get, sessionMiddleware)
|
||||||
|
|
||||||
e.POST("/user", userHandler.GetUserIdByEmail)
|
e.POST("/user", userHandler.GetUserIdByEmail)
|
||||||
e.POST("/logout", userHandler.Logout, hankoMiddleware.Session(sessionManager))
|
e.POST("/logout", userHandler.Logout, sessionMiddleware)
|
||||||
|
|
||||||
if cfg.Account.AllowDeletion {
|
if cfg.Account.AllowDeletion {
|
||||||
e.DELETE("/user", userHandler.Delete, hankoMiddleware.Session(sessionManager))
|
e.DELETE("/user", userHandler.Delete, sessionMiddleware)
|
||||||
}
|
}
|
||||||
|
|
||||||
healthHandler := NewHealthHandler()
|
healthHandler := NewHealthHandler()
|
||||||
@ -117,7 +119,7 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
}
|
}
|
||||||
|
|
||||||
webauthn := e.Group("/webauthn")
|
webauthn := e.Group("/webauthn")
|
||||||
webauthnRegistration := webauthn.Group("/registration", hankoMiddleware.Session(sessionManager))
|
webauthnRegistration := webauthn.Group("/registration", sessionMiddleware)
|
||||||
webauthnRegistration.POST("/initialize", webauthnHandler.BeginRegistration)
|
webauthnRegistration.POST("/initialize", webauthnHandler.BeginRegistration)
|
||||||
webauthnRegistration.POST("/finalize", webauthnHandler.FinishRegistration)
|
webauthnRegistration.POST("/finalize", webauthnHandler.FinishRegistration)
|
||||||
|
|
||||||
@ -125,7 +127,7 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
webauthnLogin.POST("/initialize", webauthnHandler.BeginAuthentication)
|
webauthnLogin.POST("/initialize", webauthnHandler.BeginAuthentication)
|
||||||
webauthnLogin.POST("/finalize", webauthnHandler.FinishAuthentication)
|
webauthnLogin.POST("/finalize", webauthnHandler.FinishAuthentication)
|
||||||
|
|
||||||
webauthnCredentials := webauthn.Group("/credentials", hankoMiddleware.Session(sessionManager))
|
webauthnCredentials := webauthn.Group("/credentials", sessionMiddleware)
|
||||||
webauthnCredentials.GET("", webauthnHandler.ListCredentials)
|
webauthnCredentials.GET("", webauthnHandler.ListCredentials)
|
||||||
webauthnCredentials.PATCH("/:id", webauthnHandler.UpdateCredential)
|
webauthnCredentials.PATCH("/:id", webauthnHandler.UpdateCredential)
|
||||||
webauthnCredentials.DELETE("/:id", webauthnHandler.DeleteCredential)
|
webauthnCredentials.DELETE("/:id", webauthnHandler.DeleteCredential)
|
||||||
@ -135,7 +137,7 @@ func NewPublicRouter(cfg *config.Config, persister persistence.Persister, promet
|
|||||||
passcodeLogin.POST("/initialize", passcodeHandler.Init)
|
passcodeLogin.POST("/initialize", passcodeHandler.Init)
|
||||||
passcodeLogin.POST("/finalize", passcodeHandler.Finish)
|
passcodeLogin.POST("/finalize", passcodeHandler.Finish)
|
||||||
|
|
||||||
email := e.Group("/emails", hankoMiddleware.Session(sessionManager))
|
email := e.Group("/emails", sessionMiddleware)
|
||||||
email.GET("", emailHandler.List)
|
email.GET("", emailHandler.List)
|
||||||
email.POST("", emailHandler.Create)
|
email.POST("", emailHandler.Create)
|
||||||
email.DELETE("/:id", emailHandler.Delete)
|
email.DELETE("/:id", emailHandler.Delete)
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
echojwt "github.com/labstack/echo-jwt/v4"
|
echojwt "github.com/labstack/echo-jwt/v4"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/teamhanko/hanko/backend/config"
|
||||||
"github.com/teamhanko/hanko/backend/session"
|
"github.com/teamhanko/hanko/backend/session"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Session is a convenience function to create a middleware.JWT with custom JWT verification
|
// Session is a convenience function to create a middleware.JWT with custom JWT verification
|
||||||
func Session(generator session.Manager) echo.MiddlewareFunc {
|
func Session(cfg *config.Config, generator session.Manager) echo.MiddlewareFunc {
|
||||||
c := echojwt.Config{
|
c := echojwt.Config{
|
||||||
ContextKey: "session",
|
ContextKey: "session",
|
||||||
TokenLookup: "header:Authorization:Bearer,cookie:hanko",
|
TokenLookup: fmt.Sprintf("header:Authorization:Bearer,cookie:%s", cfg.Session.Cookie.GetName()),
|
||||||
ParseTokenFunc: parseToken(generator),
|
ParseTokenFunc: parseToken(generator),
|
||||||
ErrorHandler: func(c echo.Context, err error) error {
|
ErrorHandler: func(c echo.Context, err error) error {
|
||||||
return echo.NewHTTPError(http.StatusUnauthorized).SetInternal(err)
|
return echo.NewHTTPError(http.StatusUnauthorized).SetInternal(err)
|
||||||
|
|||||||
@ -28,6 +28,7 @@ type manager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type cookieConfig struct {
|
type cookieConfig struct {
|
||||||
|
Name string
|
||||||
Domain string
|
Domain string
|
||||||
HttpOnly bool
|
HttpOnly bool
|
||||||
SameSite http.SameSite
|
SameSite http.SameSite
|
||||||
@ -67,11 +68,13 @@ func NewManager(jwkManager hankoJwk.Manager, config config.Config) (Manager, err
|
|||||||
} else {
|
} else {
|
||||||
audience = []string{config.Webauthn.RelyingParty.Id}
|
audience = []string{config.Webauthn.RelyingParty.Id}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &manager{
|
return &manager{
|
||||||
jwtGenerator: g,
|
jwtGenerator: g,
|
||||||
sessionLength: duration,
|
sessionLength: duration,
|
||||||
issuer: config.Session.Issuer,
|
issuer: config.Session.Issuer,
|
||||||
cookieConfig: cookieConfig{
|
cookieConfig: cookieConfig{
|
||||||
|
Name: config.Session.Cookie.GetName(),
|
||||||
Domain: config.Session.Cookie.Domain,
|
Domain: config.Session.Cookie.Domain,
|
||||||
HttpOnly: config.Session.Cookie.HttpOnly,
|
HttpOnly: config.Session.Cookie.HttpOnly,
|
||||||
SameSite: sameSite,
|
SameSite: sameSite,
|
||||||
@ -116,7 +119,7 @@ func (m *manager) Verify(token string) (jwt.Token, error) {
|
|||||||
// GenerateCookie creates a new session cookie for the given user
|
// GenerateCookie creates a new session cookie for the given user
|
||||||
func (m *manager) GenerateCookie(token string) (*http.Cookie, error) {
|
func (m *manager) GenerateCookie(token string) (*http.Cookie, error) {
|
||||||
return &http.Cookie{
|
return &http.Cookie{
|
||||||
Name: "hanko",
|
Name: m.cookieConfig.Name,
|
||||||
Value: token,
|
Value: token,
|
||||||
Domain: m.cookieConfig.Domain,
|
Domain: m.cookieConfig.Domain,
|
||||||
Path: "/",
|
Path: "/",
|
||||||
|
|||||||
Reference in New Issue
Block a user