Golang JWT使用

在环境GOPATH/src 里:

           go get github.com/dgrijalva/jwt-go

思路:

          1.在登陆时,创建Tocken

          2. 再次请求时,验证TOcken

实体代码

import   "github.com/dgrijalva/jwt-go"
// 建立统一标准需求 实体
type OceanClainms struct {
    Username string `json:username`
    Uid uint `json:"uid"`
    // JWT 标准需求
    jwt.StandardClaims
}
// 用户登陆实体
type User struct {
     Uid uint
     UserName string
     UserPass string
}
// 登陆返回的实体
type ResultMessage struct {
Message string
Tocken string
}
 
// 登陆操作
func Login(UserName string,passward string) ResultMessage{
    var result ResultMessage
    var user User
    user.UserName="zx"
    user.UserPass="123"
    if user.UserName==UserName && user.UserPass==passward{  // 登陆成功
        // 登陆成功 创建Tocken
        tocken,err:=CreateTocken(user.UserName,user.Uid)
        if err!=nil{
            result.Message=err.Error()
        }else {
            result.Message="sucess"
            result.Tocken=tocken
        }
    }else {
        result.Message=errors.New("用户名或密码错误!").Error()
    }
    return result
}

// Base64 加密串
var key ="c2RmZGZzZGN4Y3g1MzMqJWRGZmQp"
// 创建Tocken
func CreateTocken(UserName string,Uid uint) (string,error){
    clims := OceanClainms{Username:UserName ,Uid:Uid, StandardClaims:jwt.StandardClaims{
        //  过期时间
        ExpiresAt: time.Now().Add(time.Hour*24*7).Unix(),
        //  生成时间
        IssuedAt: time.Now().Unix(),
        // 生成者
        Issuer: "Service",
        },
    }
    tonken :=jwt.NewWithClaims(jwt.SigningMethodHS256,clims)
// 注意 这里的Key 是Base64加密字符串 tonkenStr,err:
= tonken.SignedString([]byte(key)) if err!=nil{ // TODO } return tonkenStr,err }

建立验证Tocken 中间件,当用户登后做其他请求时,必须传递Tocken在中间件里做验证,验证成功方能请求

// Tocken 验证中间件
func AuthMiddleware() gin.HandlerFunc{
    return func(context *gin.Context) {
        // 获取传递过来的Tocken
        tokenString :=context.GetHeader("Authorization")
        if tokenString ==""|| tokenString[0:7]!="Bearer "{
            context.JSON(http.StatusUnauthorized,gin.H{
                "messsage":"Token验证失败",
            })
            context.Abort()
            return
        }
        // 解析Tocker
        tonken,clains,err:=ParseTocker(tokenString[7:])
        if err!=nil ||!tonken.Valid{  // 判断Tocken是否有效
            context.JSON(http.StatusUnauthorized,gin.H{
                "messsage":"Tocken无效",
            })
            context.Abort()
            return
        }
        context.Set("user",clains.Username)
        context.Next()
    }
}
// 解析Tocken
// tonkenString  Tocken字符串
func ParseTocker(tonkenString string) (*jwt.Token,OceanClainms,error){
 clains :=OceanClainms{}
 tonken,err :=jwt.ParseWithClaims(tonkenString,&clains,func(token *jwt.Token) (interface{},error){
           return []byte(key),nil
    })
 return tonken,clains,err
}

main方法 :登陆成功生成Tocken, 除登陆外的请求皆加Tocken验证

package main

import (
    "errors"
    "github.com/dgrijalva/jwt-go"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func main()  {
    engin :=gin.Default()
    // 登陆请求成功后返回Tocken
    engin.GET("/login", func(c *gin.Context) {
        var user User
        err:=c.ShouldBind(&user)   // 将参数转为User对像
        if err!=nil{
            c.JSON(http.StatusBadRequest,"请求错误:参数名称不对")
            return
        }
        result:= Login(user.UserName,user.UserPass) // 获取返回信息
        c.JSON(http.StatusOK,gin.H{
            "message":result.Message,
            "Tocken": result.Tocken,
        })
    })
    // 登陆后所有的请求,加入中间件验证Tocken
    engin.GET("/add",AuthMiddleware(), func(context *gin.Context) {
        context.JSON(http.StatusOK,gin.H{"request":"OK"})
    })
    engin.Run(":1200")
}

完整代码

package main

import (
    "errors"
    "github.com/dgrijalva/jwt-go"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)
// Base64 加密串
var key ="c2RmZGZzZGN4Y3g1MzMqJWRGZmQp"
// 建立统一标准需求 实体
type OceanClainms struct {
    Username string `json:username`
    Uid uint `json:"uid"`
    // JWT 标准需求
    jwt.StandardClaims
}
// 用户登陆实体
type User struct {
     Uid uint
     UserName string
     UserPass string
}

// 创建Tocken
func CreateTocken(UserName string,Uid uint) (string,error){
    clims := OceanClainms{Username:UserName ,Uid:Uid, StandardClaims:jwt.StandardClaims{
        //  过期时间
        ExpiresAt: time.Now().Add(time.Hour*24*7).Unix(),
        //  生成时间
        IssuedAt: time.Now().Unix(),
        // 生成者
        Issuer: "Service",
        },
    }
    tonken :=jwt.NewWithClaims(jwt.SigningMethodHS256,clims)
    tonkenStr,err:= tonken.SignedString([]byte(key))
    if err!=nil{
        // TODO
    }
    return tonkenStr,err
}

// 解析Tocken
// tonkenString  Tocken字符串
func ParseTocker(tonkenString string) (*jwt.Token,OceanClainms,error){
 clains :=OceanClainms{}
 tonken,err :=jwt.ParseWithClaims(tonkenString,&clains,func(token *jwt.Token) (interface{},error){
           return []byte(key),nil
    })
 return tonken,clains,err
}

// 登陆返回的实体
type ResultMessage struct {
    Message string
    Tocken string
}

// 登陆操作
func Login(UserName string,passward string) ResultMessage{
    var result ResultMessage
    var user User
    user.UserName="zx"
    user.UserPass="123"
    if user.UserName==UserName && user.UserPass==passward{  // 登陆成功
        // 登陆成功 创建Tocken
        tocken,err:=CreateTocken(user.UserName,user.Uid)
        if err!=nil{
            result.Message=err.Error()
        }else {
            result.Message="sucess"
            result.Tocken=tocken
        }
    }else {
        result.Message=errors.New("用户名或密码错误!").Error()
    }
    return result
}

// Tocken 验证中间件
func AuthMiddleware() gin.HandlerFunc{
    return func(context *gin.Context) {
        // 获取传递过来的Tocken
        tokenString :=context.GetHeader("Authorization")
        if tokenString ==""|| tokenString[0:7]!="Bearer "{
            context.JSON(http.StatusUnauthorized,gin.H{
                "messsage":"Token验证失败",
            })
            context.Abort()
            return
        }
        // 解析Tocker
        tonken,clains,err:=    ParseTocker(tokenString[7:])
        if err!=nil ||!tonken.Valid{  // 判断Tocken是否有效
            context.JSON(http.StatusUnauthorized,gin.H{
                "messsage":"Tocken无效",
            })
            context.Abort()
            return
        }
        context.Set("user",clains.Username)
        context.Next()
    }
}

func main()  {
    engin :=gin.Default()
    // 登陆请求成功后返回Tocken
    engin.GET("/login", func(c *gin.Context) {
        var user User
        err:=c.ShouldBind(&user)   // 将参数转为User对像
        if err!=nil{
            c.JSON(http.StatusBadRequest,"请求错误:参数名称不对")
            return
        }
        result:= Login(user.UserName,user.UserPass) // 获取返回信息
        c.JSON(http.StatusOK,gin.H{
            "message":result.Message,
            "Tocken": result.Tocken,
        })
    })
    // 加入中间件验证Tocken
    engin.GET("/add",AuthMiddleware(), func(context *gin.Context) {
        context.JSON(http.StatusOK,gin.H{"request":"OK"})
    })
    engin.Run(":1200")
}

 PostMan请求

 

 

 

 上面是Tocken不正确的结果,下面是正确Tocken的结果

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章