1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-23 10:44:02 +00:00
fiber/middleware/csrf/config.go

193 lines
4.8 KiB
Go
Raw Normal View History

2020-11-11 15:25:35 +01:00
package csrf
import (
"fmt"
2021-03-01 16:25:32 -05:00
"net/textproto"
"strings"
2020-11-11 15:25:35 +01:00
"time"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
)
// Config defines the config for middleware.
type Config struct {
// Next defines a function to skip this middleware when returned true.
//
// Optional. Default: nil
Next func(c *fiber.Ctx) bool
2020-11-11 18:19:53 +01:00
// KeyLookup is a string in the form of "<source>:<key>" that is used
2020-11-11 15:25:35 +01:00
// to extract token from the request.
// Possible values:
// - "header:<name>"
// - "query:<name>"
// - "param:<name>"
// - "form:<name>"
// - "cookie:<name>"
2020-11-11 18:19:53 +01:00
//
// Optional. Default: "header:X-CSRF-Token"
KeyLookup string
2020-11-11 15:25:35 +01:00
2020-11-14 00:45:55 +01:00
// Name of the session cookie. This cookie will store session key.
2020-12-10 10:45:21 +05:30
// Optional. Default value "csrf_".
2020-11-14 00:45:55 +01:00
CookieName string
// Domain of the CSRF cookie.
// Optional. Default value "".
CookieDomain string
// Path of the CSRF cookie.
// Optional. Default value "".
CookiePath string
// Indicates if CSRF cookie is secure.
// Optional. Default value false.
CookieSecure bool
// Indicates if CSRF cookie is HTTP only.
// Optional. Default value false.
CookieHTTPOnly bool
// Value of SameSite cookie.
2021-12-02 02:41:44 -04:00
// Optional. Default value "Lax".
2020-11-14 00:45:55 +01:00
CookieSameSite string
2020-11-11 15:25:35 +01:00
// Decides whether cookie should last for only the browser sesison.
// Ignores Expiration if set to true
CookieSessionOnly bool
2020-11-11 15:25:35 +01:00
// Expiration is the duration before csrf token will expire
//
// Optional. Default: 1 * time.Hour
Expiration time.Duration
// Store is used to store the state of the middleware
//
2020-11-11 15:57:38 +01:00
// Optional. Default: memory.New()
2020-11-11 15:25:35 +01:00
Storage fiber.Storage
// Context key to store generated CSRF token into context.
2020-11-11 18:19:53 +01:00
// If left empty, token will not be stored in context.
2020-11-11 15:25:35 +01:00
//
2020-11-11 18:19:53 +01:00
// Optional. Default: ""
2020-11-11 15:25:35 +01:00
ContextKey string
2020-11-11 18:19:53 +01:00
// KeyGenerator creates a new CSRF token
2020-11-11 15:25:35 +01:00
//
2020-11-11 18:19:53 +01:00
// Optional. Default: utils.UUID
2020-11-11 16:41:26 +01:00
KeyGenerator func() string
2020-11-11 15:25:35 +01:00
// Deprecated, please use Expiration
CookieExpires time.Duration
2020-11-11 18:19:53 +01:00
2020-11-14 00:45:55 +01:00
// Deprecated, please use Cookie* related fields
Cookie *fiber.Cookie
2020-11-11 18:19:53 +01:00
// Deprecated, please use KeyLookup
TokenLookup string
// ErrorHandler is executed when an error is returned from fiber.Handler.
//
// Optional. Default: DefaultErrorHandler
ErrorHandler fiber.ErrorHandler
2021-03-01 16:25:32 -05:00
// extractor returns the csrf token from the request based on KeyLookup
extractor func(c *fiber.Ctx) (string, error)
2020-11-11 15:25:35 +01:00
}
// ConfigDefault is the default config
var ConfigDefault = Config{
2020-11-14 00:45:55 +01:00
KeyLookup: "header:X-Csrf-Token",
CookieName: "csrf_",
2021-12-02 02:41:44 -04:00
CookieSameSite: "Lax",
2020-11-14 00:45:55 +01:00
Expiration: 1 * time.Hour,
KeyGenerator: utils.UUID,
ErrorHandler: defaultErrorHandler,
2021-03-01 16:25:32 -05:00
extractor: csrfFromHeader("X-Csrf-Token"),
}
// default ErrorHandler that process return error from fiber.Handler
var defaultErrorHandler = func(c *fiber.Ctx, err error) error {
return fiber.ErrForbidden
2020-11-11 15:25:35 +01:00
}
// Helper function to set default values
func configDefault(config ...Config) Config {
// Return default config if nothing provided
if len(config) < 1 {
return ConfigDefault
}
// Override default config
cfg := config[0]
// Set default values
2020-11-11 18:19:53 +01:00
if cfg.TokenLookup != "" {
fmt.Println("[CSRF] TokenLookup is deprecated, please use KeyLookup")
2020-11-11 18:34:46 +01:00
cfg.KeyLookup = cfg.TokenLookup
2020-11-11 15:25:35 +01:00
}
2020-11-14 03:09:53 +01:00
if int(cfg.CookieExpires.Seconds()) > 0 {
2020-11-11 15:25:35 +01:00
fmt.Println("[CSRF] CookieExpires is deprecated, please use Expiration")
2020-11-11 18:34:46 +01:00
cfg.Expiration = cfg.CookieExpires
2020-11-11 18:19:53 +01:00
}
2020-11-14 00:45:55 +01:00
if cfg.Cookie != nil {
fmt.Println("[CSRF] Cookie is deprecated, please use Cookie* related fields")
if cfg.Cookie.Name != "" {
cfg.CookieName = cfg.Cookie.Name
}
if cfg.Cookie.Domain != "" {
cfg.CookieDomain = cfg.Cookie.Domain
}
if cfg.Cookie.Path != "" {
cfg.CookiePath = cfg.Cookie.Path
}
cfg.CookieSecure = cfg.Cookie.Secure
cfg.CookieHTTPOnly = cfg.Cookie.HTTPOnly
if cfg.Cookie.SameSite != "" {
cfg.CookieSameSite = cfg.Cookie.SameSite
}
}
2020-11-11 18:19:53 +01:00
if cfg.KeyLookup == "" {
cfg.KeyLookup = ConfigDefault.KeyLookup
2020-11-11 15:25:35 +01:00
}
2020-11-13 18:34:01 +01:00
if int(cfg.Expiration.Seconds()) <= 0 {
2020-11-11 15:25:35 +01:00
cfg.Expiration = ConfigDefault.Expiration
}
2020-11-14 00:45:55 +01:00
if cfg.CookieName == "" {
cfg.CookieName = ConfigDefault.CookieName
}
if cfg.CookieSameSite == "" {
cfg.CookieSameSite = ConfigDefault.CookieSameSite
2020-11-11 15:25:35 +01:00
}
2020-11-11 16:41:26 +01:00
if cfg.KeyGenerator == nil {
cfg.KeyGenerator = ConfigDefault.KeyGenerator
2020-11-11 15:25:35 +01:00
}
if cfg.ErrorHandler == nil {
cfg.ErrorHandler = ConfigDefault.ErrorHandler
}
2020-11-11 15:25:35 +01:00
2021-03-01 16:25:32 -05:00
// Generate the correct extractor to get the token from the correct location
selectors := strings.Split(cfg.KeyLookup, ":")
if len(selectors) != 2 {
panic("[CSRF] KeyLookup must in the form of <source>:<key>")
}
// By default we extract from a header
cfg.extractor = csrfFromHeader(textproto.CanonicalMIMEHeaderKey(selectors[1]))
switch selectors[0] {
case "form":
cfg.extractor = csrfFromForm(selectors[1])
case "query":
cfg.extractor = csrfFromQuery(selectors[1])
case "param":
cfg.extractor = csrfFromParam(selectors[1])
case "cookie":
cfg.extractor = csrfFromCookie(selectors[1])
}
2020-11-11 15:25:35 +01:00
return cfg
}