github.com/gofiber/fiber/v2@v2.47.0/docs/api/middleware/keyauth.md (about) 1 --- 2 id: keyauth 3 title: Keyauth 4 --- 5 6 Key auth middleware provides a key based authentication. 7 8 ## Signatures 9 10 ```go 11 func New(config ...Config) fiber.Handler 12 ``` 13 14 ## Examples 15 16 ```go 17 package main 18 19 import ( 20 "crypto/sha256" 21 "crypto/subtle" 22 "github.com/gofiber/fiber/v2" 23 "github.com/gofiber/fiber/v2/middleware/keyauth" 24 ) 25 26 var ( 27 apiKey = "correct horse battery staple" 28 ) 29 30 func validateAPIKey(c *fiber.Ctx, key string) (bool, error) { 31 hashedAPIKey := sha256.Sum256([]byte(apiKey)) 32 hashedKey := sha256.Sum256([]byte(key)) 33 34 if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { 35 return true, nil 36 } 37 return false, keyauth.ErrMissingOrMalformedAPIKey 38 } 39 40 func main() { 41 app := fiber.New() 42 43 // note that the keyauth middleware needs to be defined before the routes are defined! 44 app.Use(keyauth.New(keyauth.Config{ 45 KeyLookup: "cookie:access_token", 46 Validator: validateAPIKey, 47 })) 48 49 app.Get("/", func(c *fiber.Ctx) error { 50 return c.SendString("Successfully authenticated!") 51 }) 52 53 app.Listen(":3000") 54 } 55 ``` 56 57 **Test:** 58 59 ```bash 60 # No api-key specified -> 400 missing 61 curl http://localhost:3000 62 #> missing or malformed API Key 63 64 curl --cookie "access_token=correct horse battery staple" http://localhost:3000 65 #> Successfully authenticated! 66 67 curl --cookie "access_token=Clearly A Wrong Key" http://localhost:3000 68 #> missing or malformed API Key 69 ``` 70 71 For a more detailed example, see also the [`github.com/gofiber/recipes`](https://github.com/gofiber/recipes) repository and specifically the `fiber-envoy-extauthz` repository and the [`keyauth example`](https://github.com/gofiber/recipes/blob/master/fiber-envoy-extauthz/authz/main.go) code. 72 73 74 ### Authenticate only certain endpoints 75 76 If you want to authenticate only certain endpoints, you can use the `Config` of keyauth and apply a filter function (eg. `authFilter`) like so 77 78 ```go 79 package main 80 81 import ( 82 "crypto/sha256" 83 "crypto/subtle" 84 "github.com/gofiber/fiber/v2" 85 "github.com/gofiber/fiber/v2/middleware/keyauth" 86 "regexp" 87 "strings" 88 ) 89 90 var ( 91 apiKey = "correct horse battery staple" 92 protectedURLs = []*regexp.Regexp{ 93 regexp.MustCompile("^/authenticated$"), 94 regexp.MustCompile("^/auth2$"), 95 } 96 ) 97 98 func validateAPIKey(c *fiber.Ctx, key string) (bool, error) { 99 hashedAPIKey := sha256.Sum256([]byte(apiKey)) 100 hashedKey := sha256.Sum256([]byte(key)) 101 102 if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { 103 return true, nil 104 } 105 return false, keyauth.ErrMissingOrMalformedAPIKey 106 } 107 108 func authFilter(c *fiber.Ctx) bool { 109 originalURL := strings.ToLower(c.OriginalURL()) 110 111 for _, pattern := range protectedURLs { 112 if pattern.MatchString(originalURL) { 113 return false 114 } 115 } 116 return true 117 } 118 119 func main() { 120 app := fiber.New() 121 122 app.Use(keyauth.New(keyauth.Config{ 123 Next: authFilter, 124 KeyLookup: "cookie:access_token", 125 Validator: validateAPIKey, 126 })) 127 128 app.Get("/", func(c *fiber.Ctx) error { 129 return c.SendString("Welcome") 130 }) 131 app.Get("/authenticated", func(c *fiber.Ctx) error { 132 return c.SendString("Successfully authenticated!") 133 }) 134 app.Get("/auth2", func(c *fiber.Ctx) error { 135 return c.SendString("Successfully authenticated 2!") 136 }) 137 138 app.Listen(":3000") 139 } 140 ``` 141 142 Which results in this 143 144 ```bash 145 # / does not need to be authenticated 146 curl http://localhost:3000 147 #> Welcome 148 149 # /authenticated needs to be authenticated 150 curl --cookie "access_token=correct horse battery staple" http://localhost:3000/authenticated 151 #> Successfully authenticated! 152 153 # /auth2 needs to be authenticated too 154 curl --cookie "access_token=correct horse battery staple" http://localhost:3000/auth2 155 #> Successfully authenticated 2! 156 ``` 157 158 ### Specifying middleware in the handler 159 160 ```go 161 package main 162 163 import ( 164 "crypto/sha256" 165 "crypto/subtle" 166 "github.com/gofiber/fiber/v2" 167 "github.com/gofiber/fiber/v2/middleware/keyauth" 168 ) 169 170 const ( 171 apiKey = "my-super-secret-key" 172 ) 173 174 func main() { 175 app := fiber.New() 176 177 authMiddleware := keyauth.New(keyauth.Config{ 178 Validator: func(c *fiber.Ctx, key string) (bool, error) { 179 hashedAPIKey := sha256.Sum256([]byte(apiKey)) 180 hashedKey := sha256.Sum256([]byte(key)) 181 182 if subtle.ConstantTimeCompare(hashedAPIKey[:], hashedKey[:]) == 1 { 183 return true, nil 184 } 185 return false, keyauth.ErrMissingOrMalformedAPIKey 186 }, 187 }) 188 189 app.Get("/", func(c *fiber.Ctx) error { 190 return c.SendString("Welcome") 191 }) 192 193 app.Get("/allowed", authMiddleware, func(c *fiber.Ctx) error { 194 return c.SendString("Successfully authenticated!") 195 }) 196 197 app.Listen(":3000") 198 } 199 ``` 200 201 Which results in this 202 203 ```bash 204 # / does not need to be authenticated 205 curl http://localhost:3000 206 #> Welcome 207 208 # /allowed needs to be authenticated too 209 curl --header "Authorization: Bearer my-super-secret-key" http://localhost:3000/allowed 210 #> Successfully authenticated! 211 ``` 212 213 ## Config 214 215 ```go 216 // Config defines the config for middleware. 217 type Config struct { 218 // Next defines a function to skip middleware. 219 // Optional. Default: nil 220 Next func(*fiber.Ctx) bool 221 222 // SuccessHandler defines a function which is executed for a valid key. 223 // Optional. Default: nil 224 SuccessHandler fiber.Handler 225 226 // ErrorHandler defines a function which is executed for an invalid key. 227 // It may be used to define a custom error. 228 // Optional. Default: 401 Invalid or expired key 229 ErrorHandler fiber.ErrorHandler 230 231 // KeyLookup is a string in the form of "<source>:<name>" that is used 232 // to extract key from the request. 233 // Optional. Default value "header:Authorization". 234 // Possible values: 235 // - "header:<name>" 236 // - "query:<name>" 237 // - "form:<name>" 238 // - "param:<name>" 239 // - "cookie:<name>" 240 KeyLookup string 241 242 // AuthScheme to be used in the Authorization header. 243 // Optional. Default value "Bearer". 244 AuthScheme string 245 246 // Validator is a function to validate key. 247 Validator func(*fiber.Ctx, string) (bool, error) 248 249 // Context key to store the bearertoken from the token into context. 250 // Optional. Default: "token". 251 ContextKey string 252 } 253 ``` 254 255 ## Default Config 256 257 ```go 258 var ConfigDefault = Config{ 259 SuccessHandler: func(c *fiber.Ctx) error { 260 return c.Next() 261 }, 262 ErrorHandler: func(c *fiber.Ctx, err error) error { 263 if err == ErrMissingOrMalformedAPIKey { 264 return c.Status(fiber.StatusUnauthorized).SendString(err.Error()) 265 } 266 return c.Status(fiber.StatusUnauthorized).SendString("Invalid or expired API Key") 267 }, 268 KeyLookup: "header:" + fiber.HeaderAuthorization, 269 AuthScheme: "Bearer", 270 ContextKey: "token", 271 } 272 ```