github.com/gofiber/fiber/v2@v2.47.0/middleware/csrf/config.go (about) 1 package csrf 2 3 import ( 4 "log" 5 "net/textproto" 6 "strings" 7 "time" 8 9 "github.com/gofiber/fiber/v2" 10 "github.com/gofiber/fiber/v2/utils" 11 ) 12 13 // Config defines the config for middleware. 14 type Config struct { 15 // Next defines a function to skip this middleware when returned true. 16 // 17 // Optional. Default: nil 18 Next func(c *fiber.Ctx) bool 19 20 // KeyLookup is a string in the form of "<source>:<key>" that is used 21 // to create an Extractor that extracts the token from the request. 22 // Possible values: 23 // - "header:<name>" 24 // - "query:<name>" 25 // - "param:<name>" 26 // - "form:<name>" 27 // - "cookie:<name>" 28 // 29 // Ignored if an Extractor is explicitly set. 30 // 31 // Optional. Default: "header:X-CSRF-Token" 32 KeyLookup string 33 34 // Name of the session cookie. This cookie will store session key. 35 // Optional. Default value "csrf_". 36 CookieName string 37 38 // Domain of the CSRF cookie. 39 // Optional. Default value "". 40 CookieDomain string 41 42 // Path of the CSRF cookie. 43 // Optional. Default value "". 44 CookiePath string 45 46 // Indicates if CSRF cookie is secure. 47 // Optional. Default value false. 48 CookieSecure bool 49 50 // Indicates if CSRF cookie is HTTP only. 51 // Optional. Default value false. 52 CookieHTTPOnly bool 53 54 // Value of SameSite cookie. 55 // Optional. Default value "Lax". 56 CookieSameSite string 57 58 // Decides whether cookie should last for only the browser sesison. 59 // Ignores Expiration if set to true 60 CookieSessionOnly bool 61 62 // Expiration is the duration before csrf token will expire 63 // 64 // Optional. Default: 1 * time.Hour 65 Expiration time.Duration 66 67 // Store is used to store the state of the middleware 68 // 69 // Optional. Default: memory.New() 70 Storage fiber.Storage 71 72 // Context key to store generated CSRF token into context. 73 // If left empty, token will not be stored in context. 74 // 75 // Optional. Default: "" 76 ContextKey string 77 78 // KeyGenerator creates a new CSRF token 79 // 80 // Optional. Default: utils.UUID 81 KeyGenerator func() string 82 83 // Deprecated: Please use Expiration 84 CookieExpires time.Duration 85 86 // Deprecated: Please use Cookie* related fields 87 Cookie *fiber.Cookie 88 89 // Deprecated: Please use KeyLookup 90 TokenLookup string 91 92 // ErrorHandler is executed when an error is returned from fiber.Handler. 93 // 94 // Optional. Default: DefaultErrorHandler 95 ErrorHandler fiber.ErrorHandler 96 97 // Extractor returns the csrf token 98 // 99 // If set this will be used in place of an Extractor based on KeyLookup. 100 // 101 // Optional. Default will create an Extractor based on KeyLookup. 102 Extractor func(c *fiber.Ctx) (string, error) 103 } 104 105 const HeaderName = "X-Csrf-Token" 106 107 // ConfigDefault is the default config 108 var ConfigDefault = Config{ 109 KeyLookup: "header:" + HeaderName, 110 CookieName: "csrf_", 111 CookieSameSite: "Lax", 112 Expiration: 1 * time.Hour, 113 KeyGenerator: utils.UUID, 114 ErrorHandler: defaultErrorHandler, 115 Extractor: CsrfFromHeader(HeaderName), 116 } 117 118 // default ErrorHandler that process return error from fiber.Handler 119 func defaultErrorHandler(_ *fiber.Ctx, _ error) error { 120 return fiber.ErrForbidden 121 } 122 123 // Helper function to set default values 124 func configDefault(config ...Config) Config { 125 // Return default config if nothing provided 126 if len(config) < 1 { 127 return ConfigDefault 128 } 129 130 // Override default config 131 cfg := config[0] 132 133 // Set default values 134 if cfg.TokenLookup != "" { 135 log.Printf("[Warning] - [CSRF] TokenLookup is deprecated, please use KeyLookup\n") 136 cfg.KeyLookup = cfg.TokenLookup 137 } 138 if int(cfg.CookieExpires.Seconds()) > 0 { 139 log.Printf("[Warning] - [CSRF] CookieExpires is deprecated, please use Expiration\n") 140 cfg.Expiration = cfg.CookieExpires 141 } 142 if cfg.Cookie != nil { 143 log.Printf("[Warning] - [CSRF] Cookie is deprecated, please use Cookie* related fields\n") 144 if cfg.Cookie.Name != "" { 145 cfg.CookieName = cfg.Cookie.Name 146 } 147 if cfg.Cookie.Domain != "" { 148 cfg.CookieDomain = cfg.Cookie.Domain 149 } 150 if cfg.Cookie.Path != "" { 151 cfg.CookiePath = cfg.Cookie.Path 152 } 153 cfg.CookieSecure = cfg.Cookie.Secure 154 cfg.CookieHTTPOnly = cfg.Cookie.HTTPOnly 155 if cfg.Cookie.SameSite != "" { 156 cfg.CookieSameSite = cfg.Cookie.SameSite 157 } 158 } 159 if cfg.KeyLookup == "" { 160 cfg.KeyLookup = ConfigDefault.KeyLookup 161 } 162 if int(cfg.Expiration.Seconds()) <= 0 { 163 cfg.Expiration = ConfigDefault.Expiration 164 } 165 if cfg.CookieName == "" { 166 cfg.CookieName = ConfigDefault.CookieName 167 } 168 if cfg.CookieSameSite == "" { 169 cfg.CookieSameSite = ConfigDefault.CookieSameSite 170 } 171 if cfg.KeyGenerator == nil { 172 cfg.KeyGenerator = ConfigDefault.KeyGenerator 173 } 174 if cfg.ErrorHandler == nil { 175 cfg.ErrorHandler = ConfigDefault.ErrorHandler 176 } 177 178 // Generate the correct extractor to get the token from the correct location 179 selectors := strings.Split(cfg.KeyLookup, ":") 180 181 const numParts = 2 182 if len(selectors) != numParts { 183 panic("[CSRF] KeyLookup must in the form of <source>:<key>") 184 } 185 186 if cfg.Extractor == nil { 187 // By default we extract from a header 188 cfg.Extractor = CsrfFromHeader(textproto.CanonicalMIMEHeaderKey(selectors[1])) 189 190 switch selectors[0] { 191 case "form": 192 cfg.Extractor = CsrfFromForm(selectors[1]) 193 case "query": 194 cfg.Extractor = CsrfFromQuery(selectors[1]) 195 case "param": 196 cfg.Extractor = CsrfFromParam(selectors[1]) 197 case "cookie": 198 cfg.Extractor = CsrfFromCookie(selectors[1]) 199 } 200 } 201 202 return cfg 203 }