zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    第五周总结 8.11
    第四周总结 8.2
    第三周总结7.27
    PHP实验四
    PHP实验一
    PHP实验三
    软件工程课程总结
    《梦断代码》阅读笔记03
    找水王
    评价搜狗输入法
  • 原文地址:https://www.cnblogs.com/finghi/p/15572418.html
Copyright © 2011-2022 走看看