gpt4 book ai didi

前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 32 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?

 什么是JWT?

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,也是目前前后端分离项目中普遍使用的认证技术. 本文介绍如何在Golang Gin Web框架中使用JWT认证中间件以及模拟测试, 以供参考, 关于JWT详细原理可以参考

  • JWT RFC: https://tools.ietf.org/html/rfc7519
  • JWT IETF: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html
  • JSON Web Token入门教程: http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

主要流程 。

  • 初始化Gin引擎
  • 定义获取Token的接口, 访问该接口, 内部自动生成JWT令牌, 并返回给前端
  • 定义需要认证的路由接口, 使用JWT中间件进行认证, 中间件由
  • 利用GoConvey(Golang的测试框架,集成go test, 支持终端和浏览器模式), 构造客户端, 填写Token, 模拟前端访问
  • JWT中间件进行认证, 认证通过则返回消息体, 否则直接返回401或其他错误

流程图 。

前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?

该流程图描述了服务端代码中的Token构造, 以及认证流程. 。

服务端代码 。

main.go中填充以下代码, 运行go run main.go, 开启Web服务. 。

package main  。

  。

import (  。

  jwt_lib "github.com/dgrijalva/jwt-go"  。

  "github.com/dgrijalva/jwt-go/request"  。

  "github.com/gin-gonic/gin"  。

  "log"  。

  "time"  。

)  。

  。

var (  。

  mysupersecretpassword = "unicornsAreAwesome"  。

)  。

  。

func Auth(secret string) gin.HandlerFunc {  。

  return func(c *gin.Context) {  。

    //log.Printf("Request:\n%+v", c.Request)  。

    // ParseFromRequest方法提取路径请求中的JWT令牌, 并进行验证  。

    token, err := request.ParseFromRequest(c.Request, request.OAuth2Extractor, func(token *jwt_lib.Token) (interface{}, error) {  。

      b := ([]byte(secret))  。

      //log.Printf("b:%+v", b)  。

      return b, nil  。

    })  。

  。

    log.Printf("token:%+v", token)  。

    if err != nil {  。

      c.AbortWithError(401, err)  。

    }  。

  }  。

}  。

  。

func main() {  。

  r := gin.Default()  。

  。

  public := r.Group("/api")  。

  。

  // 定义根路由, 访问http://locahost:8080/api/可以获取到token  。

  public.GET("/", func(c *gin.Context) {  。

    // Create the token New方法接受一个签名方法的接口类型(SigningMethod)参数, 返回一个Token结构指针  。

    // GetSigningMethod(签名算法algorithm)  。

    token := jwt_lib.New(jwt_lib.GetSigningMethod("HS256")) //默认是签名算法是HMAC SHA256(写成 HS256)  。

    log.Printf("token:%+v", token)  。

    //2020/12/10 22:32:02 token:&{Raw: Method:0xc00000e2a0 Header:map[alg:HS256 typ:JWT] Claims:map[] Signature: Valid:false}  。

  。

    // Set some claims 设置Id和过期时间字段, MapClaims实现了Clainms接口  。

    token.Claims = jwt_lib.MapClaims{  。

      "Id":  "Christopher",  。

      "exp": time.Now().Add(time.Hour * 1).Unix(),  。

    }  。

    // Sign and get the complete encoded token as a string // 签名并得到完整编码后的Token字符串  。

    tokenString, err := token.SignedString([]byte(mysupersecretpassword))  。

    //{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IkNocmlzdG9waGVyIiwiZXhwIjoxNjA3NjE0MzIyfQ.eQd7ztDn3706GrpitgnikKgOtzx-RHnq7cr2eqUlsZo"}  。

    if err != nil {  。

      c.JSON(500, gin.H{"message": "Could not generate token"})  。

    }  。

    c.JSON(200, gin.H{"token": tokenString})  。

  })  。

  。

  // 定义需要Token验证通过才能访问的私有接口组http://localhost:8080/api/private  。

  private := r.Group("/api/private")  。

  private.Use(Auth(mysupersecretpassword)) // 使用JWT认证中间件(带参数)  。

  。

  /*  。

    Set this header in your request to get here.  。

    Authorization: Bearer `token`  。

  */  。

  。

  // 定义具体的私有根接口:http://localhost:8080/api/private/  。

  private.GET("/", func(c *gin.Context) {  。

    c.JSON(200, gin.H{"message": "Hello from private"})  。

  })  。

  。

  r.Run("localhost:8080")  。

}  。

客户端代码 。

新建jwt_test.go文件, 填充以下代码, 运行go test执行单元测试. 。

package test_test  。

  。

import (  。

  "encoding/json"  。

  . "github.com/smartystreets/goconvey/convey" //https://github.com/smartystreets/goconvey GoConvey是Golang的测试框架,集成go test, 支持终端和浏览器模式.  。

  "io/ioutil"  。

  "log"  。

  "net/http"  。

  "strings"  。

  "testing"  。

)  。

  。

type User struct {  。

  Username string `json:"username"`  。

  Password string `json:"password"`  。

}  。

  。

type Response struct {  。

  Token string `json:"token"`  。

}  。

  。

func createNewsUser(username, password string) *User {  。

  return &User{username, password}  。

}  。

  。

func TestLogin(t *testing.T) {  。

  Convey("Should be able to login", t, func() {  。

    user := createNewsUser("jonas", "1234")  。

    jsondata, _ := json.Marshal(user)  。

    userData := strings.NewReader(string(jsondata))  。

    log.Printf("userData:%+v", userData)  。

    // 这里模拟用户登录, 实际上后台没有使用用户名和密码, 该接口直接返回内部生成的Token  。

    req, _ := http.NewRequest("GET", "http://localhost:8080/api/", userData)  。

    req.Header.Set("Content-Type", "application/json")  。

    client := &http.Client{}  。

    res, _ := client.Do(req)  。

    //log.Printf("res:%+v", res)  。

    So(res.StatusCode, ShouldEqual, 200) //对响应码进行断言, 期望得到状态码为200  。

  。

    Convey("Should be able to parse body", func() { //解析响应体  。

      body, err := ioutil.ReadAll(res.Body)  。

      defer res.Body.Close()  。

      So(err, ShouldBeNil)  。

      Convey("Should be able to get json back", func() {  。

        responseData := new(Response)  。

        err := json.Unmarshal(body, responseData)  。

        So(err, ShouldBeNil)  。

        log.Printf("responseData:%s", responseData)  。

        Convey("Should be able to be authorized", func() {  。

          token := responseData.Token //提取Token  。

          log.Printf("token:%s", token)  。

          // 构造带Token的请求  。

          req, _ := http.NewRequest("GET", "http://localhost:8080/api/private", nil)  。

          req.Header.Set("Authorization", "Bearer "+token) //设置认证头  。

          client = &http.Client{}  。

          res, _ := client.Do(req)  。

          body, err := ioutil.ReadAll(res.Body)  。

          if err != nil {  。

            log.Printf("Read body failed, %s", err.Error())  。

          }  。

          log.Printf("Body:%s", string(body))  。

          So(res.StatusCode, ShouldEqual, 200)  。

        })  。

      })  。

    })  。

  })  。

}  。

参考文档 。

gin-gonic/contrib/jwt中间件: https://github.com/gin-gonic/contrib/tree/master/jwt 。

原文地址:https://mp.weixin.qq.com/s/dEptFz4KTrPczZB-K4AiKg

最后此篇关于前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?的文章就讲到这里了,如果你想了解更多关于前后端分离必备, Golang Gin中如何使用JWT(JsonWebToken)中间件?的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com