Go语言:JWT鉴权

Go语言:JWT鉴权

JWT是什么

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

使用场景

  • Authorization (授权) :这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) :对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。

JWT和OAuth的区别

  • OAuth2是一种授权框架 ,JWT是一种认证协议。
  • 无论使用哪种方式切记用HTTPS来保证数据的安全性。
  • OAuth2用在使用第三方账号登录的情况(比如使用weibo,qq,github登录某个app),而JWT是用在前后端分离,,需要简单的对后台API进行保护时使用。

Go语言使用JWT

Go语言中已实现多个可用JWT库,比较常用的有jwt-go、jwt-auth两个:

  1. jwt-go :Golang implementation of JSON Web Tokens (JWT)

    go get github.com/dgrijalva/jwt-go

  2. jwt-auth:JWT middleware for Golang http servers with many configuration options

    go get github.com/adam-hanna/jwt-auth

jwt-go库

jwt-go创建Token对象有两种方法:New和NewWithClaims。前者使用库默认Claims,后者使用自定义Claims。自定义Claims继承jwt.StandardClaims并添加需要的用户信息(示例所示)。

type Token struct {
	Raw       string                 // The raw token.  Populated when you Parse a token
	Method    SigningMethod          // The signing method used or to be used
	Header    map[string]interface{} // The first segment of the token
	Claims    Claims                 // The second segment of the token
	Signature string                 // The third segment of the token.  Populated when you Parse a token
	Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
}

// Create a new Token.  Takes a signing method
func New(method SigningMethod) *Token {
	return NewWithClaims(method, MapClaims{})
}

func NewWithClaims(method SigningMethod, claims Claims) *Token {
	return &Token{
		Header: map[string]interface{}{
			"typ": "JWT",
			"alg": method.Alg(),
		},
		Claims: claims,
		Method: method,
	}
}

示例(jwt-go):

package util

import (
	"fmt"
	"time"

	"github.com/dgrijalva/jwt-go"
)

// Claims custom token
type Claims struct {
	PlayerID  int32 `json:"player_id"`  // 玩家
	Channel   int32 `json:"channel"`    // 渠道
	Version   int32 `json:"version"`    // 版本
	LoginType int32 `json:"login_type"` // 登录方式
	jwt.StandardClaims                  
}

// CreateToken create token
func CreateToken(claims *Claims) (signedToken string, success bool) {
	claims.ExpiresAt = time.Now().Add(time.Minute * 30).Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err := token.SignedString([]byte("secret"))
	if err != nil {
		return
	}

	success = true
	return
}

// ValidateToken validate token
func ValidateToken(signedToken string) (claims *Claims, success bool) {
	token, err := jwt.ParseWithClaims(signedToken, &Claims{},
		func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("unexpected login method %v", token.Header["alg"])
			}
			return []byte("secret"), nil
		})

	if err != nil {
		return
	}

	claims, ok := token.Claims.(*Claims)
	if ok && token.Valid {
		success = true
		return
	}

	return
}

参考:

  1. 认识JWT:https://www.cnblogs.com/cjsblog/p/9277677.html

你可能感兴趣的:(Go语言:JWT鉴权)