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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM