jwt

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 10, 2022 License: MIT Imports: 10 Imported by: 0

README

JWT useful for Gin Framework

GoDoc Go.Dev reference codecov Action Status Go Report Card Licence Tag

This is a jwt useful for Gin framework.

It uses jwt-go to provide a jwt encode and decode token.

Usage

Download and install using go module:

export GO111MODULE=on
go get github.com/things-go/gin-jwt

Import it in your code:

import "github.com/things-go/gin-jwt"

Download and install without using go module:

go get github.com/things-go/gin-jwt

Import it in your code:

import "github.com/things-go/gin-jwt"

Example

Please see the example file.

package main

import (
	"log"
	"math/rand"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"

	ginjwt "github.com/things-go/gin-jwt"
)

const identityKey = "identify"

// User demo
type User struct {
	Uid      int64
	Username string
}

type login struct {
	Username string `form:"username" json:"username" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

type Claims struct {
	jwt.RegisteredClaims
	Identity User `json:"identity"`
}

func main() {
	// jwt auth
	auth, err := ginjwt.New(ginjwt.Config{
		SignConfig: ginjwt.SignConfig{
			Algorithm: "HS256",
			Key:       []byte("secret key"),
		},

		// NewLookup new lookup
		// lookup is a string in the form of "<source>:<name>[:<headerName>]" that is used
		// to extract token from the request.
		// use like "header:<name>[:<headerName>],query:<name>,cookie:<name>,param:<name>"
		// Optional, Default value "header:Authorization:Bearer".
		// Possible values:
		// - "header:<name>:<headerName>", <headerName> is a special string in the header, Possible value is "Bearer"
		// - "query:<name>"
		// - "cookie:<name>"
		// - "param:<name>"
		TokenLookup: "header:Authorization:Bearer,query:token,cookie:jwt",
	})
	if err != nil {
		log.Fatal("JWT Error:" + err.Error())
	}

	service := &Service{auth}

	r := gin.New()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())
	r.Use(service.CheckAuth("/login"))
	{
		r.POST("/login", service.Login)
		r.GET("/hello", helloHandler)
	}
	if err = http.ListenAndServe(":8000", r); err != nil {
		log.Fatal(err)
	}
}

type Service struct {
	auth *ginjwt.Auth
}

func (sf *Service) Login(c *gin.Context) {
	var req login
	if err := c.ShouldBind(&req); err != nil {
		c.JSON(http.StatusBadRequest, nil)
		return
	}
	username := req.Username
	password := req.Password

	if (username == "admin" && password == "admin") ||
		(username == "test" && password == "test") {
		uid := rand.Int63()

		expiredAt := time.Now().Add(time.Hour)
		t, err := sf.auth.NewWithClaims(Claims{
			RegisteredClaims: jwt.RegisteredClaims{
				ExpiresAt: jwt.NewNumericDate(expiredAt),
			},
			Identity: User{uid, username},
		})
		if err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
			return
		}
		log.Printf("uid: %d, token: %s", uid, t)
		c.JSON(http.StatusOK, gin.H{"token": t, "tm": expiredAt})
		return
	}
	c.JSON(http.StatusBadRequest, gin.H{"msg": "账号或密码错"})
}

func checkPrefix(s string, prefixes ...string) bool {
	for _, p := range prefixes {
		if strings.HasPrefix(s, p) {
			return true
		}
	}
	return false
}

func (sf *Service) CheckAuth(excludePrefixes ...string) gin.HandlerFunc {
	return func(c *gin.Context) {
		if !checkPrefix(c.Request.URL.Path, excludePrefixes...) {
			tk, err := sf.auth.Get(c.Request)
			if err != nil {
				c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": err.Error()})
				return
			}
			v, err := sf.auth.ParseWithClaims(tk, &Claims{})
			if err != nil {
				c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": err.Error()})
				return
			}
			u := v.Claims.(*Claims)
			c.Set(identityKey, &u.Identity)
		}
		c.Next()
	}
}

func helloHandler(c *gin.Context) {
	user, _ := c.Get(identityKey)
	u := user.(*User)
	c.JSON(http.StatusOK, gin.H{
		"uid":      u.Uid,
		"username": user.(*User).Username,
		"text":     "Hello World.",
	})
}

Demo

Please run _example/main.go file and listen 8000 port.

go run _example/main.go

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrMissingToken can be thrown by follow
	// if authing with a HTTP header, the Auth header needs to be set
	// if authing with URL Query, the query token variable is empty
	// if authing with a cookie, the token cookie is empty
	// if authing with parameter in path, the parameter in path is empty
	ErrMissingToken = request.ErrNoTokenInRequest
	// ErrInvalidAuthHeader indicates auth header is invalid
	ErrInvalidAuthHeader = errors.New("auth header is invalid")
	// ErrInvalidSigningAlgorithm indicates signing algorithm is invalid,
	// needs to be HS256, HS384, HS512, RS256, RS384 or RS512
	ErrInvalidSigningAlgorithm = errors.New("invalid signing algorithm")

	// ErrNoPubKeyFile indicates that the given public key is unreadable
	ErrNoPubKeyFile = errors.New("public key file unreadable")
	// ErrInvalidPubKey indicates the the given public key is invalid
	ErrInvalidPubKey = errors.New("public key invalid")
	// ErrNoPrivKeyFile indicates that the given private key is unreadable
	ErrNoPrivKeyFile = errors.New("private key file unreadable")
	// ErrInvalidPrivKey indicates that the given private key is invalid
	ErrInvalidPrivKey = errors.New("private key invalid")
	// ErrMissingSecretKey indicates Secret key is required
	ErrMissingSecretKey = errors.New("secret key is required")
)

Functions

func FromCookie added in v0.2.0

func FromCookie(r *http.Request, key string) (string, error)

FromCookie get token from Cookie key is cookie key

func FromHeader added in v0.2.0

func FromHeader(r *http.Request, key, prefix string) (string, error)

FromHeader get token from header key is header key, like "Authorization" prefix is a string in the header, like "Bearer", if it is empty, it will return value.

func FromQuery added in v0.2.0

func FromQuery(r *http.Request, key string) (string, error)

FromQuery get token from query key is query key

Types

type ArgumentExtractor added in v1.2.0

type ArgumentExtractor string

ArgumentExtractor extracts a token from request arguments. This includes a POSTed form or GET URL arguments. This extractor calls `ParseMultipartForm` on the request

func (ArgumentExtractor) ExtractToken added in v1.2.0

func (e ArgumentExtractor) ExtractToken(r *http.Request) (string, error)

type Auth

type Auth struct {
	*Signature
	*Lookup
}

Auth provides a Json-Web-Token authentication implementation. The token then needs to be passed in the Authentication header. Example: Authorization:Bearer XXX_TOKEN_XXX

func New

func New(c Config) (*Auth, error)

New for check error with Config

type Config

type Config struct {
	SignConfig

	// TokenLookup is a string in the form of "<source>:<name>[:<headerName>]" that is used
	// to extract token from the request.
	// use like "header:<name>[:<headerName>],query:<name>,cookie:<name>,param:<name>"
	// Optional, Default value "header:Authorization:Bearer".
	// Possible values:
	// - "header:<name>:<headerName>", <headerName> is a special string in the header, Possible value is "Bearer"
	// - "query:<name>"
	// - "cookie:<name>"
	// - "param:<name>"
	TokenLookup string
}

Config auth config

type Cookie struct {
	// For cookie
	// Duration that a cookie is valid.
	CookieMaxAge time.Duration
	// Allow insecure cookies for development over http
	SecureCookie bool
	// Allow cookies to be accessed client side for development
	CookieHTTPOnly bool
	// Allow cookie domain change for development
	CookieDomain string
	// CookieName allow cookie name change for development
	CookieName string
	// CookieSameSite allow use http.SameSite cookie param
	CookieSameSite http.SameSite
}

Cookie for cookie set jwt token

func (*Cookie) RemoveCookie added in v0.0.2

func (sf *Cookie) RemoveCookie(c *gin.Context)

RemoveCookie can be used by clients to remove the jwt cookie (if set)

func (*Cookie) SetCookie added in v0.0.2

func (sf *Cookie) SetCookie(c *gin.Context, tokenString string)

SetCookie can be used by clients to set the jwt cookie

type CookieExtractor added in v1.2.0

type CookieExtractor string

CookieExtractor extracts a token from cookie.

func (CookieExtractor) ExtractToken added in v1.2.0

func (e CookieExtractor) ExtractToken(r *http.Request) (string, error)

type HeaderExtractor added in v1.2.0

type HeaderExtractor struct {
	// The key of the header
	// Required
	Key string
	// Strips 'Bearer ' prefix from bearer token string.
	// Possible value is "Bearer"
	// Optional
	Prefix string
}

HeaderExtractor is an extractor for finding a token in a header. Looks at each specified header in order until there's a match

func (HeaderExtractor) ExtractToken added in v1.2.0

func (e HeaderExtractor) ExtractToken(r *http.Request) (string, error)

type Lookup added in v0.2.0

type Lookup struct {
	// contains filtered or unexported fields
}

Lookup is a tool that looks up the token

func NewLookup added in v0.2.0

func NewLookup(lookup string) *Lookup

NewLookup new lookup lookup is a string in the form of "<source>:<name>[:<prefix>]" that is used to extract token from the request. use like "header:<name>[:<prefix>],query:<name>,cookie:<name>,param:<name>" Optional, Default value "header:Authorization:Bearer". Possible values: - "header:<name>:<prefix>", <prefix> is a special string in the header, Possible value is "Bearer" - "query:<name>" - "cookie:<name>"

func (*Lookup) Get added in v1.2.0

func (sf *Lookup) Get(r *http.Request) (string, error)

Get get token from header, defined in NewLookup

type SignConfig added in v0.2.0

type SignConfig struct {
	// 支持签名算法: HS256, HS384, HS512, RS256, RS384 or RS512
	// Optional, Default HS256.
	Algorithm string
	// Secret key used for signing.
	// Required, HS256, HS384, HS512.
	Key []byte
	// Private key file for asymmetric algorithms,
	// Public key file for asymmetric algorithms
	// Required, RS256, RS384 or RS512.
	PrivKeyFile, PubKeyFile string
}

SignConfig Signature config

type Signature added in v0.2.0

type Signature struct {
	// contains filtered or unexported fields
}

Signature provides a Json-Web-Token authentication implementation.

func NewSignature added in v0.2.0

func NewSignature(c SignConfig) (*Signature, error)

NewSignature new signature with Config

func (*Signature) NewWithClaims added in v0.2.2

func (sf *Signature) NewWithClaims(claims jwt.Claims) (string, error)

NewWithClaims creates a new Token with the claims.

func (*Signature) ParseWithClaims added in v0.2.2

func (sf *Signature) ParseWithClaims(tokenString string, claims jwt.Claims) (*jwt.Token, error)

ParseWithClaims parse token string for claims

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL