JWT代码实现

在Go中可以直接使用github.com/dgrijalva/jwt-go简单实现Token的生成和有效性检验。
如果存在私密的文件,则需要使用使用密码对称加密。jwt生成的token在没有加密的情况下,需要使用https传输数据,确保数据安全。
更多请参考:JSON Web Token 入门教程

下面是代码实现:

package main

import (
	"errors"
	"fmt"
	"log"
	"time"

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

type UserInfo struct {
	ID uint64
	Username string
}

const SecrectStr string ="hello world"

func CreateToken(user *UserInfo)(tokenss string,err error){
	//自定义claim
	claim := jwt.MapClaims{
		"id":       user.ID,
		"username": user.Username,
		"nbf":      time.Now().Unix(),
		"iat":      time.Now().Unix(),
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256,claim)
	// 签名后的token格式说明
	// 示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1NzUyODUyNzUsImlkIjoxLCJuYmYiOjE1NzUyODUyNzUsInVzZXJuYW1lIjoicGVuZ2oifQ.bDe8UZYLxvmrK7gHcuK8TrlnoiMsIm3Jo_f0-YYle7E
	// 使用符号.,被分割成了三段
	// 第一段base64解码之后:{"alg":"HS256","typ":"JWT"}
	// 第二段base64解码之后:{"iat":1575285275,"id":1,"nbf":1575285275,"username":"pengj"},是原始的数据。
	// 第三段是使用SigningMethodHS256加密之后的文本
	tokenss,err  = token.SignedString([]byte(SecrectStr))
	return
}

func secret()jwt.Keyfunc{
	return func(token *jwt.Token) (i interface{}, e error) {
		return []byte(SecrectStr),nil
		return i, e
	}
}

func ParseToken(tokenss string)(user *UserInfo,err error){
	user = &UserInfo{}
	token,err := jwt.Parse(tokenss,secret())
	if err != nil{
		return
	}
	claim,ok := token.Claims.(jwt.MapClaims)
	if !ok{
		err = errors.New("cannot convert claim to mapclaim")
		return
	}
	//验证token,如果token被修改过则为false
	if  !token.Valid{
		err = errors.New("token is invalid")
		return
	}

	user.ID =uint64(claim["id"].(float64))
	user.Username = claim["username"].(string)
	return
}

func main(){
	user := UserInfo{ID:1, Username: "pengj"}
	tokenStr, err := CreateToken(&user)
	if err != nil {
		panic(err)
	}
	log.Println("tokenStr:", tokenStr)
	u , err := ParseToken(tokenStr)
	if err != nil {
		panic(err)
	}
	fmt.Println(u.ID, u.Username)
}
复制代码