Skip to content
This repository has been archived by the owner on May 19, 2023. It is now read-only.

Commit

Permalink
v0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Fenny committed Apr 6, 2020
1 parent a859d84 commit 80f81b9
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 2 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
### Install
```
go get -u github.com/gofiber/fiber
go get -u github.com/gofiber/keyauth
```
### Example
```go
package main

import (
"github.com/gofiber/fiber"
"github.com/gofiber/keyauth"
)

func main() {
app := fiber.New()

app.Use(keyauth.New(keyauth.Config{
TokenLookup: "cookie:access_token",
ContextKey: "my_token"
}))

app.Get("/", func(c *fiber.Ctx) {
c.Send(c.Locals("my_token"))
})

app.Listen(3000)
}
```
### Test
```curl
curl -v --cookie "access_token=hello_world" http://localhost:3000
```
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/gofiber/keyauth

go 1.11

require github.com/gofiber/fiber v1.8.3
require github.com/gofiber/fiber v1.8.431
149 changes: 148 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,152 @@
// πŸš€ Fiber is an Express inspired web framework written in Go with πŸ’–
// πŸ“Œ API Documentation: https://fiber.wiki
// πŸ“ Github Repository: https://github.com/gofiber/fiber

package keyauth

import (
"errors"
"strings"

"github.com/gofiber/fiber"
)

// Config holds the configuration of the middleware. It is completely optional
// and should only be provided if your application uses token keys that are not
// RFC6750-compliant.
type Config struct {
// Filter defines a function to skip middleware.
// Optional. Default: nil
Filter func(*fiber.Ctx) bool

// TokenLookup is a string in the form of "<source>:<name>" that is used
// to extract token from the request.
// Optional. Default value "header:authorization".
// Possible values:
// - "header:<name>"
// - "query:<name>"
// - "param:<name>"
// - "form:<name>"
// - "cookie:<name>"
TokenLookup string

// Context key to store the bearertoken from the token into context.
// Optional. Default: "token".
ContextKey string

// AuthScheme to be used in the Authorization header.
// Optional. Default: "Bearer".
AuthScheme string

// ErrorHandler defines a function which is executed for an invalid or missing token.
// It may be used to define a custom error.
// Optional. Default: 401 Unauthorized
ErrorHandler func(*fiber.Ctx, error)
}

// New creates a middleware for use in Fiber.
func New(config ...Config) func(*fiber.Ctx) {
// Init config
var cfg Config
if len(config) > 0 {
cfg = config[0]
}
if cfg.TokenLookup == "" {
cfg.TokenLookup = "header:" + fiber.HeaderAuthorization
}
if cfg.ContextKey == "" {
cfg.ContextKey = "token"
}
if cfg.AuthScheme == "" && strings.ToLower(cfg.TokenLookup) == "header:authorization" {
cfg.AuthScheme = "Bearer"
}
if cfg.ErrorHandler == nil {
cfg.ErrorHandler = func(c *fiber.Ctx, err error) {
c.SendStatus(401)
}
}
// Initialize
parts := strings.Split(cfg.TokenLookup, ":")
extractor := bearerFromHeader(parts[1], cfg.AuthScheme)
switch parts[0] {
case "query":
extractor = bearerFromQuery(parts[1])
case "param":
extractor = bearerFromParam(parts[1])
case "form":
extractor = bearerFromForm(parts[1])
case "cookie":
extractor = bearerFromCookie(parts[1])
}

return func(c *fiber.Ctx) {
// Filter request to skip middleware
if cfg.Filter != nil && cfg.Filter(c) {
c.Next()
return
}
// Extract bearer token
token, err := extractor(c)
if err != nil {
cfg.ErrorHandler(c, err)
return
}
c.Locals(cfg.ContextKey, token)
c.Next()
}
}

// bearerFromHeader returns a function that extracts token from the request header.
func bearerFromHeader(header string, authScheme string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
auth := c.Get(header)
l := len(authScheme)
if len(auth) > l+1 && auth[:l] == authScheme {
return auth[l+1:], nil
}
return "", errors.New("Missing or malformed Bearer token")
}
}

// bearerFromQuery returns a function that extracts token from the query string.
func bearerFromQuery(param string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
token := c.Query(param)
if token == "" {
return "", errors.New("Missing or malformed Bearer token")
}
return token, nil
}
}

// bearerFromParam returns a function that extracts token from the url param string.
func bearerFromParam(param string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
token := c.Params(param)
if token == "" {
return "", errors.New("Missing or malformed Bearer token")
}
return token, nil
}
}

// bearerFromParam returns a function that extracts token from the url param string.
func bearerFromForm(param string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
token := c.FormValue(param)
if token == "" {
return "", errors.New("Missing or malformed Bearer token")
}
return token, nil
}
}

// bearerFromCookie returns a function that extracts token from the named cookie.
func bearerFromCookie(name string) func(c *fiber.Ctx) (string, error) {
return func(c *fiber.Ctx) (string, error) {
token := c.Cookies(name)
if token == "" {
return "", errors.New("Missing or malformed Bearer token")
}
return token, nil
}
}
5 changes: 5 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// πŸš€ Fiber is an Express inspired web framework written in Go with πŸ’–
// πŸ“Œ API Documentation: https://fiber.wiki
// πŸ“ Github Repository: https://github.com/gofiber/fiber

package keyauth

0 comments on commit 80f81b9

Please # to comment.