• 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的结果

  • 相关阅读:
    第07组 Alpha冲刺 (2/6)
    第07组Alpha冲刺(1/6)
    第四次作业
    面试题练习
    SpringMVC访问静态资源
    MyBatis基础
    Spring注解和jdk注解
    自动代理生成器
    aspect xml
    Spring-案例
  • 原文地址:https://www.cnblogs.com/yingger/p/13445575.html
Copyright © 2020-2023  润新知