All Projects → gofiber → jwt

gofiber / jwt

Licence: MIT license
🧬 JWT middleware for Fiber

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to jwt

Boilerplate
🚧 Boilerplate for 🚀 Fiber
Stars: ✭ 73 (-73.84%)
Mutual labels:  fiber
React Three Fiber
🇨🇭 A React renderer for Three.js
Stars: ✭ 16,097 (+5669.53%)
Mutual labels:  fiber
YACLib
Yet Another Concurrency Library
Stars: ✭ 193 (-30.82%)
Mutual labels:  fiber
Tina
Tina is a teeny tiny, header only, coroutine and job library.
Stars: ✭ 125 (-55.2%)
Mutual labels:  fiber
Lightio
LightIO is a userland implemented green thread library for ruby
Stars: ✭ 165 (-40.86%)
Mutual labels:  fiber
Fre
👻 Tiny Footprint Concurrent UI library for Fiber.
Stars: ✭ 3,195 (+1045.16%)
Mutual labels:  fiber
Sylar
C++高性能分布式服务器框架,webserver,websocket server,自定义tcp_server(包含日志模块,配置模块,线程模块,协程模块,协程调度模块,io协程调度模块,hook模块,socket模块,bytearray序列化,http模块,TcpServer模块,Websocket模块,Https模块等, Smtp邮件模块, MySQL, SQLite3, ORM,Redis,Zookeeper)
Stars: ✭ 895 (+220.79%)
Mutual labels:  fiber
fiber-swagger
fiber middleware to automatically generate RESTful API documentation with Swagger 2.0.
Stars: ✭ 238 (-14.7%)
Mutual labels:  fiber
Fiber
⚡️ Express inspired web framework written in Go
Stars: ✭ 17,334 (+6112.9%)
Mutual labels:  fiber
ikisocket
🧬 WebSocket wrapper with event management for Fiber https://github.com/gofiber/fiber. Based on Fiber WebSocket and inspired by Socket.io
Stars: ✭ 92 (-67.03%)
Mutual labels:  fiber
Fiber Ext
stackful-coroutines for PHP
Stars: ✭ 142 (-49.1%)
Mutual labels:  fiber
Minicoro
Single header asymmetric stackful cross-platform coroutine library in pure C.
Stars: ✭ 164 (-41.22%)
Mutual labels:  fiber
Just React
「React技术揭秘」 一本自顶向下的React源码分析书
Stars: ✭ 3,897 (+1296.77%)
Mutual labels:  fiber
Docs
📚 Documentation for 🚀 Fiber
Stars: ✭ 121 (-56.63%)
Mutual labels:  fiber
utils
⚡ A collection of common functions but with better performance, less allocations and less dependencies created for Fiber.
Stars: ✭ 21 (-92.47%)
Mutual labels:  fiber
Websocket
🧬 WebSocket middleware for Fiber
Stars: ✭ 59 (-78.85%)
Mutual labels:  fiber
React Conf 17 Videos
Find that one presentation you missed!
Stars: ✭ 182 (-34.77%)
Mutual labels:  fiber
helmet
🧬 Helmet middleware for Fiber
Stars: ✭ 63 (-77.42%)
Mutual labels:  fiber
keyauth
🧬 Key Authentication for Fiber
Stars: ✭ 58 (-79.21%)
Mutual labels:  fiber
storage
📦 Premade storage drivers for 🚀 Fiber
Stars: ✭ 156 (-44.09%)
Mutual labels:  fiber

JSON Web Tokens

Release Discord Test Security Linter

JWT returns a JSON Web Token (JWT) auth middleware. For valid token, it sets the user in Ctx.Locals and calls next handler. For invalid token, it returns "401 - Unauthorized" error. For missing token, it returns "400 - Bad Request" error.

Special thanks and credits to Echo

Install

This middleware supports Fiber v1 & v2, install accordingly.

go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/jwt/v3
go get -u github.com/golang-jwt/jwt/v4

Signature

jwtware.New(config ...jwtware.Config) func(*fiber.Ctx) error

Config

Property Type Description Default
Filter func(*fiber.Ctx) bool Defines a function to skip middleware nil
SuccessHandler func(*fiber.Ctx) error SuccessHandler defines a function which is executed for a valid token. nil
ErrorHandler func(*fiber.Ctx, error) error ErrorHandler defines a function which is executed for an invalid token. 401 Invalid or expired JWT
SigningKey interface{} Signing key to validate token. Used as fallback if SigningKeys has length 0. nil
SigningKeys map[string]interface{} Map of signing keys to validate token with kid field usage. nil
SigningMethod string Signing method, used to check token signing method. Possible values: HS256, HS384, HS512, ES256, ES384, ES512, RS256, RS384, RS512 "HS256"
ContextKey string Context key to store user information from the token into context. "user"
Claims jwt.Claim Claims are extendable claims data defining token content. jwt.MapClaims{}
TokenLookup string TokenLookup is a string in the form of <source>:<name> that is used "header:Authorization"
AuthScheme string AuthScheme to be used in the Authorization header. "Bearer"
KeySetURL string KeySetURL location of JSON file with signing keys. ""
KeyRefreshSuccessHandler func(j *KeySet) KeyRefreshSuccessHandler defines a function which is executed for a valid refresh of signing keys. nil
KeyRefreshErrorHandler func(j *KeySet, err error) KeyRefreshErrorHandler defines a function which is executed for an invalid refresh of signing keys. nil
KeyRefreshInterval *time.Duration KeyRefreshInterval is the duration to refresh the JWKs in the background via a new HTTP request. nil
KeyRefreshRateLimit *time.Duration KeyRefreshRateLimit limits the rate at which refresh requests are granted. nil
KeyRefreshTimeout *time.Duration KeyRefreshTimeout is the duration for the context used to create the HTTP request for a refresh of the JWKs. 1min
KeyRefreshUnknownKID bool KeyRefreshUnknownKID indicates that the JWKs refresh request will occur every time a kid that isn't cached is seen. false
KeyFunc func() jwt.Keyfunc KeyFunc defines a user-defined function that supplies the public key for a token validation. jwtKeyFunc

HS256 Example

package main

import (
	"time"

	"github.com/gofiber/fiber/v2"

	jwtware "github.com/gofiber/jwt/v3"
	"github.com/golang-jwt/jwt/v4"
)

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

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// JWT Middleware
	app.Use(jwtware.New(jwtware.Config{
		SigningKey: []byte("secret"),
	}))

	// Restricted Routes
	app.Get("/restricted", restricted)

	app.Listen(":3000")
}

func login(c *fiber.Ctx) error {
	user := c.FormValue("user")
	pass := c.FormValue("pass")

	// Throws Unauthorized error
	if user != "john" || pass != "doe" {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	// Create the Claims
	claims := jwt.MapClaims{
		"name":  "John Doe",
		"admin": true,
		"exp":   time.Now().Add(time.Hour * 72).Unix(),
	}

	// Create token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte("secret"))
	if err != nil {
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(fiber.Map{"token": t})
}

func accessible(c *fiber.Ctx) error {
	return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
	user := c.Locals("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.SendString("Welcome " + name)
}

HS256 Test

Login using username and password to retrieve a token.

curl --data "user=john&pass=doe" http://localhost:3000/login

Response

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"
}

Request a restricted resource using the token in Authorization request header.

curl localhost:3000/restricted -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0NjE5NTcxMzZ9.RB3arc4-OyzASAaUhC2W3ReWaXAt_z2Fd3BN4aWTgEY"

Response

Welcome John Doe

RS256 Example

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"log"
	"time"

	"github.com/gofiber/fiber/v2"

	jwtware "github.com/gofiber/jwt/v3"
	"github.com/golang-jwt/jwt/v4"
)

var (
	// Obviously, this is just a test example. Do not do this in production.
	// In production, you would have the private key and public key pair generated
	// in advance. NEVER add a private key to any GitHub repo.
	privateKey *rsa.PrivateKey
)

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

	// Just as a demo, generate a new private/public key pair on each run. See note above.
	rng := rand.Reader
	var err error
	privateKey, err = rsa.GenerateKey(rng, 2048)
	if err != nil {
		log.Fatalf("rsa.GenerateKey: %v", err)
	}

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// JWT Middleware
	app.Use(jwtware.New(jwtware.Config{
		SigningMethod: "RS256",
		SigningKey:    privateKey.Public(),
	}))

	// Restricted Routes
	app.Get("/restricted", restricted)

	app.Listen(":3000")
}

func login(c *fiber.Ctx) error {
	user := c.FormValue("user")
	pass := c.FormValue("pass")

	// Throws Unauthorized error
	if user != "john" || pass != "doe" {
		return c.SendStatus(fiber.StatusUnauthorized)
	}

	// Create the Claims
	claims := jwt.MapClaims{
		"name":  "John Doe",
		"admin": true,
		"exp":   time.Now().Add(time.Hour * 72).Unix(),
	}

	// Create token
	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)

	// Generate encoded token and send it as response.
	t, err := token.SignedString(privateKey)
	if err != nil {
		log.Printf("token.SignedString: %v", err)
		return c.SendStatus(fiber.StatusInternalServerError)
	}

	return c.JSON(fiber.Map{"token": t})
}

func accessible(c *fiber.Ctx) error {
	return c.SendString("Accessible")
}

func restricted(c *fiber.Ctx) error {
	user := c.Locals("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	name := claims["name"].(string)
	return c.SendString("Welcome " + name)
}

RS256 Test

The RS256 is actually identical to the HS256 test above.

JWKs Test

The tests are identical to basic JWT tests above, with exception that KeySetURL to valid public keys collection in JSON format should be supplied.

Custom KeyFunc example

KeyFunc defines a user-defined function that supplies the public key for a token validation. The function shall take care of verifying the signing algorithm and selecting the proper key. A user-defined KeyFunc can be useful if tokens are issued by an external party.

When a user-defined KeyFunc is provided, SigningKey, SigningKeys, and SigningMethod are ignored. This is one of the three options to provide a token validation key. The order of precedence is a user-defined KeyFunc, SigningKeys and SigningKey. Required if neither SigningKeys nor SigningKey is provided. Default to an internal implementation verifying the signing algorithm and selecting the proper key.

package main

import (
	"fmt"
  "github.com/gofiber/fiber/v2"

  jwtware "github.com/gofiber/jwt/v3"
  "github.com/golang-jwt/jwt/v4"
)

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

	app.Use(jwtware.New(jwtware.Config{
		KeyFunc: customKeyFunc(),
	}))

	app.Get("/ok", func(c *fiber.Ctx) error {
		return c.SendString("OK")
	})
}

func customKeyFunc() jwt.Keyfunc {
	return func(t *jwt.Token) (interface{}, error) {
		// Always check the signing method
		if t.Method.Alg() != jwtware.HS256 {
			return nil, fmt.Errorf("Unexpected jwt signing method=%v", t.Header["alg"])
		}

		// TODO custom implementation of loading signing key like from a database
    signingKey := "secret"

		return []byte(signingKey), nil
	}
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].