golang JWT的简单使用

JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

JWT 和sessions 不同 session是存储在服务器的,每次只给客户端返回sessionid,客户端每次请求时带上sessionid即可。

但是,有多台服务器时就会出现一些麻烦,需要同步多台服务器信息,session就不好处理了。因为session是保存在服务器的,会出现A服务器能获取信息,B服务器身份信息无法通过。所以JWT就能很好的解决这个问题。服务器不需要保存信息,只需要保存加密用的secret,在用户登陆后将JWT加密生成token并发送给客户端,由客户端存储,客户端每次请求带上token。让服务器进行解析并验证。

JWT构成

一、Header (头部)

Jwt的头部承载两部分信息:

声明类型,这里是jwt
声明加密的算法 通常直接使用 HMAC SHA256

二、 Playload(载荷又称为Claim)

playload可以填充两种类型数据
1.标准中注册的声明:

iss: 签发者

sub: 面向的用户

aud: 接收方

exp: 过期时间

nbf: 生效时间

iat: 签发时间

jti: 唯一身份标识

2.自定义数据

三、Signature(签名)

签名的算法:

HMACSHA256(

    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
)

代码实现

下载

go get -u "github.com/dgrijalva/jwt-go"

引入

import (
	"errors"
	"fmt"
	"time"

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

  

定义结构体

type Userinfo struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

1、生成token  

func Macke(user *Userinfo) (token string, err error) { //生成jwt
	claims := jwt.MapClaims{ //创建一个自己的声明
		"name": user.Username,
		"pwd":  user.Password,
		"iss":  "lva",
		"nbf":  time.Now().Unix(),
		"exp":  time.Now().Add(time.Second * 4).Unix(),
		"iat":  time.Now().Unix(),
	}
then := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
fmt.Println(then) //打印&{ 0xc0000040a8 map[alg:HS256 typ:JWT] map[exp:1637212218 iat:1637212214 iss:lvjianhua name:zhansan nbf:1637212214 pwd:pwd]  false}

token, err = then.SignedString([]byte("gettoken"))
return }

2、解析token

func secret() jwt.Keyfunc { //按照这样的规则解析
	return func(t *jwt.Token) (interface{}, error) {
		return []byte("gettoken"), nil
	}
}

//解析token
func ParseToken(token string) (user *Userinfo, err error) {
	user = &Userinfo{}
	tokn, _ := jwt.Parse(token, secret())

	claim, ok := tokn.Claims.(jwt.MapClaims)
	if !ok {
		err = errors.New("解析错误")
		return
	}
	if !tokn.Valid {
		err = errors.New("令牌错误!")
		return
	}
	fmt.Println(claim)
	user.Username = claim["name"].(string) //强行转换为string类型
	user.Password = claim["pwd"].(string)  //强行转换为string类型
	return
}

  

3、实战使用  

package main

import (
	"fmt"
	token "main/jwtset"
)

func main() {
	var use = token.Userinfo{"zhansan", "pwd"}
	tkn, _ := token.Macke(&use)
	fmt.Println("_____", tkn)
	// time.Sleep(time.Second * 8)超过时间打印令牌错误
	user, err := token.ParseToken(tkn)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(user.Username)
}

  

用户请求时带上token,服务器解析token后可以获得其中的用户信息,如果token有任何改动,都无法通过验证.

内容摘抄来自:https://www.jianshu.com/p/b4e0744b44e0/

原文地址:https://www.cnblogs.com/finghi/p/15572418.html