Go语言学习之golang-jwt/jwt的教程分享

目录
  • 一、介绍
  • 二、代码实现 -对称加密 hsa(hash加密)
    • 2.1 加密生成token
    • 2.2 解密token得到原始数据
  • 三、代码实现 -非对称加密 rsa(我们这里使用rsa256)
    • 2.1 生成 rsa 私钥和公钥
    • 2.2 加密生成token
    • 2.2 解密token

一、介绍

jwt是 json web token的简称。

go使用jwt目前,主流使用的jwt库是golang-jwt/jwt

1.1 如何安装

go get -u github.com/golang-jwt/jwt/v4

1.2 import到项目里

import "github.com/golang-jwt/jwt/v4"

1.3 主流2类加密算法介绍

加密算法 代表算法 加解密
对称加密算法(hash加密) hsa HS256(最常用), HS384, HS512 期望[]byte用于签名和验证的值
非对称签名方法 rsa RS256(最常用), RS384,RS512 rsa.PrivateKey用于签名和*rsa.PublicKey验证

二、代码实现 -对称加密 hsa(hash加密)

2.1 加密生成token

我们使用 NewWithClaims(method SigningMethod, claims Claims) *Token来生成token,官方的源码如下

// NewWithClaims creates a new Token with the specified signing method and claims.
func NewWithClaims(method SigningMethod, claims Claims) *Token {
    return &Token{
        Header: map[string]interface{}{
            "typ": "JWT",
            "alg": method.Alg(),
        },
        Claims: claims,
        Method: method,
    }
}

其中我们需要 传入一个 SigningMethod 加密算法,以及一个 Claims,需要加密的内容。

SigningMethod 我们这里使用 hsa256 哈希加盟

Claims 我们封装一个 UserClaims 如下

我们调用NewWithClaims生成token代码如下:

func TestHs256(t *testing.T) {
    type User struct {
        Id   int64
        Name string
    }
    type UserClaims struct {
        User User
        jwt.RegisteredClaims
    }
    // 1 jwt.NewWithClaims生成token
    user := User{
        Id:   101,
        Name: "hisheng",
    }
    userClaims := UserClaims{
        User:             user,
        RegisteredClaims: jwt.RegisteredClaims{},
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaims)

    // 2 把token加密
    mySigningKey := []byte("ushjlwmwnwht")
    ss, err := token.SignedString(mySigningKey)
    t.Log(ss, err)
}

生成token分为两部分

1.使用jwt.NewWithClaims生产jwt.ToKen

2.把jwt.ToKen加密(这里我们需要添加一个加密key,使用base64url加密)

最后我们就得到了加密后的token,可以用来给客户端使用。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyIjp7IklkIjoxMDEsIk5hbWUiOiJoaXNoZW5nIn19.ij1kWID03f_CiELe0fPLZJ-Y64dkf2nDE-f6nGERBSE

token令牌由三部分组成,由.分隔。

前两部分是 JSON 对象,已经过base64url编码。

最后一部分是签名,以相同的方式编码。

2.2 解密token得到原始数据

我们使用官方的jwt.ParseWithClaims()来解密token,官方文档源代码如下:

func TestHs256Parse(t *testing.T) {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyIjp7IklkIjoxMDEsIk5hbWUiOiJoaXNoZW5nIn19.ij1kWID03f_CiELe0fPLZJ-Y64dkf2nDE-f6nGERBSE"

    type User struct {
        Id   int64
        Name string
    }
    type UserClaims struct {
        User User
        jwt.RegisteredClaims
    }

    token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
        return []byte("ushjlwmwnwht"), nil
    })

    if userClaims, ok := token.Claims.(*UserClaims); ok && token.Valid {
        t.Log(userClaims, userClaims.RegisteredClaims.Issuer)
    } else {
        t.Log(err)
    }
}

jwt.ParseWithClaims是parser.ParseWithClaims封装,可以自己再封装一个parser,上面的代码可以用下面的代码代替。

func TestHs256Parse2(t *testing.T) {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyIjp7IklkIjoxMDEsIk5hbWUiOiJoaXNoZW5nIn19.ij1kWID03f_CiELe0fPLZJ-Y64dkf2nDE-f6nGERBSE"

    type User struct {
        Id   int64
        Name string
    }
    type UserClaims struct {
        User User
        jwt.RegisteredClaims
    }

    parser := jwt.NewParser()
    token, err := parser.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
        return []byte("ushjlwmwnwht"), nil
    })

    if userClaims, ok := token.Claims.(*UserClaims); ok && token.Valid {
        t.Log(userClaims, userClaims.RegisteredClaims.Issuer)
    } else {
        t.Log(err)
    }
}

我们在 parser := jwt.NewParser()的时候,可以带上参数,比如parser := jwt.NewParser(WithoutClaimsValidation)// 跳过声明验证(验证过期时间、发表时间、在此之前时间)

三、代码实现 -非对称加密 rsa(我们这里使用rsa256)

2.1 生成 rsa 私钥和公钥

生成私钥

openssl genrsa -out private-key.pem

生成公钥

openssl rsa -in private-key.pem -pubout -out public-key.pem

2.2 加密生成token

func TestRs256(t *testing.T) {
    type User struct {
        Id   int64
        Name string
    }
    type UserClaims struct {
        User User
        jwt.RegisteredClaims
    }
    // 1 jwt.NewWithClaims生成token
    user := User{
        Id:   101,
        Name: "hisheng",
    }
    userClaims := UserClaims{
        User:             user,
        RegisteredClaims: jwt.RegisteredClaims{},
    }

    // Read Private Key
    privateKeyDataPem, err := ioutil.ReadFile("private-key.pem")
    if err != nil {
        log.Fatal(err)
    }
    // ParseRSAPrivateKeyFromPEM
    privateKeyData, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyDataPem)
    if err != nil {
        log.Fatal(err)
    }
    // 2 把token加密
    token, err := jwt.NewWithClaims(jwt.SigningMethodRS256, userClaims).SignedString(privateKeyData)
    t.Log(token, err)
}

2.2 解密token

func TestRs256Parse(t *testing.T) {
    tokenString := "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VyIjp7IklkIjoxMDEsIk5hbWUiOiJoaXNoZW5nIn19.GOS-d7iwaLDCSaSsBpArbtH-3JlD1KFNoJeyZjQ6Xv4XySo599WY784mVj-rR9kxtLYmkdAG3dPG9am6NZubHBLYWDi9b1w5gXcC7o3nAZirFGgS7bwf-7DmEetwUWzJZe-QXr1CIiVyHPU2ZCketYkIqgMGixVNfxfS5pJ5LhiUM_7J9Zlf5Kq15P9Y7U35Nu25-UXGgs-BHvH-Db6PJ4vHZq-dla_yuqRN276JBxdc24SEnML_iOHmgXVOXEWjtC_p6LmsP0VGMqwXAHN4FH0XbMzpQtTQKJgskggI41T1Ruzb9zpzJdmiL2DkeMgbvc0xVzV3CjM_AA5cUqcZaQ"
    type User struct {
        Id   int64
        Name string
    }
    type UserClaims struct {
        User User
        jwt.RegisteredClaims
    }

    token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
        // Read public Key
        publicKeyDataPem, err := ioutil.ReadFile("public-key.pem")
        if err != nil {
            log.Fatal(err)
        }
        // ParseRSAPublicKeyFromPEM
        return jwt.ParseRSAPublicKeyFromPEM(publicKeyDataPem)
    })

    if userClaims, ok := token.Claims.(*UserClaims); ok && token.Valid {
        t.Log(userClaims, userClaims.RegisteredClaims.Issuer)
    } else {
        t.Log(err)
    }

}

到此这篇关于Go语言学习之golang-jwt/jwt的教程分享的文章就介绍到这了,更多相关Go语言  golang-jwt/jwt内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • go语言使用jwt认证的实现

    目录 加密 解密 这几天在学习nodejs,进一步了解npm,学习过程中解开了以前的一个疑惑,以前不知道token可以携带信息,只以为是用来做对比的,学到了jwt身份认证,知道了如何使用的,感觉很好用,但是我不用nodejs开发,所以就去看了下golang的,做下记录 刚学,博客内容写的可能不大对,因为基本都是自己的理解,术语用的可能也不到位,但是用起来倒是没问题,见谅 golang-jwt 项目仓库 使用以下命令获取 go get github.com/golang-jwt/jwt 加密 首先

  • Go语言如何使用golang-jwt/jwt/v4进行JWT鉴权详解

    目录 前言 1.什么是JWT 2.JWT的数据结构 2.1 Header 2.2 Payload 2.3 Signature 2.4 Base64URL 3使用JWT 安装 生成Token 总结 前言 最近写的项目中用到了JWT鉴权,因此做个记录 原先的jwt-go仓库已经不再维护,迁移到了github.com/golang-jwt/jwt/v4 但是网上大多数还是v3版本的使用教程,建议使用更加安全的v4 1.什么是JWT JSON Web Token (JWT)是一个开放标准(RFC 751

  • golang之JWT实现的示例代码

    什么是JSON Web Token? JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON方式安全地传输信息.由于此信息是经过数字签名的,因此可以被验证和信任.可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对对JWT进行签名. 直白的讲jwt就是一种用户认证(区别于session.cookie)的解决方案. 出现的背景 众所周知,在jwt出现之前,我们已经有session.cookie来解决用户登

  • Golang语言学习拿捏Go反射示例教程

    目录 1. 反射简介 1.1 反射是什么? 1.2 为什么需要反射? 2. reflect包 2.1 基本反射 2.2 反射与指针 2.3 反射与对象 2.4 反射与函数 2.5 反射例子 3. 总结 1. 反射简介 1.1 反射是什么? Go语言提供了一种机制在运行时更新和检查变量的值.调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型,这种机制被称为反射.反射也可以让我们将类型本身作为第一类的值类型处理. 反射是指在程序运行期对程序本身进行访问和修改的能力,程序在编译

  • C语言学习笔记之VS2022安装使用教程

    目录 一.安装VS2022 二.创建项目测试程序 三.遇到问题 四.解决办法 一.安装VS2022 参照B站安装教程安装. Tips:选择安装信息的时候,学习C语言勾选“通用Windows平台开发”,考虑到后续会用到C++,所以勾选了“使用C++的桌面开发”.值得一提的是,安装完成之后在后续学习过程中此安装信息也是可以修改的. 二.创建项目测试程序 点击最上方状态栏调试-开始执行(不调试),运行程序. 成功! 三.遇到问题 在VS2022中,在使用scanf函数编译出错:error C4996:

  • mongodb官方的golang驱动基础使用教程分享

    前言 mongo数据库在nodejs平台有2个常用驱动,mongodb和mongoose,mongodb接口非常接近mongo数据库原生的操作方式,是helloworld之类演示代码的首选mongo数据库连接驱动,因此成为大部分nodejs初学者最先接触的mongo数据库驱动.初学者在学会mongo连接的同时,却也可悲的被helloword这种演示性质的数据库操作习惯潜移默化了. 本文主要介绍的是关于mongodb官方的golang驱动使用的相关内容,下面话不多说了,来一起看看详细的介绍吧 使用

  • Go语言学习之golang-jwt/jwt的教程分享

    目录 一.介绍 二.代码实现 -对称加密 hsa(hash加密) 2.1 加密生成token 2.2 解密token得到原始数据 三.代码实现 -非对称加密 rsa(我们这里使用rsa256) 2.1 生成 rsa 私钥和公钥 2.2 加密生成token 2.2 解密token 一.介绍 jwt是 json web token的简称. go使用jwt目前,主流使用的jwt库是golang-jwt/jwt 1.1 如何安装 go get -u github.com/golang-jwt/jwt/v

  • Golang基于JWT与Casbin身份验证授权实例详解

    目录 JWT Header Payload Signature JWT的优势 JWT的使用场景 Casbin Casbin可以做什么 Casbin不可以做什么 Casbin的工作原理 实践 登录接口请求 Token实现 使用Redis存储Token信息 用Casbin做授权管理 实现Casbin的策略 创建Todo JWT JSON Web Toekn(JWT)是一个开放标准RFC 7519,以JSON的方式进行通信,是目前最流行的一种身份验证方式之一. eyJhbGciOiJIUzI1NiIs

  • Go语言学习之goroutine详解

    什么是goroutine? Goroutine是建立在线程之上的轻量级的抽象.它允许我们以非常低的代价在同一个地址空间中并行地执行多个函数或者方法.相比于线程,它的创建和销毁的代价要小很多,并且它的调度是独立于线程的.在golang中创建一个goroutine非常简单,使用"go"关键字即可: package mainimport ( "fmt" "time")func learning() { fmt.Println("My firs

  • Go语言学习教程之goroutine和通道的示例详解

    目录 goroutine 通道 Range 和 Close Select 官方留的两道练习题 等价的二叉树 网络爬虫 源码地址 goroutine goroutine是由Go运行时管理的轻量级线程. go f(x, y, z)在一个新的goroutine中开始执行f(x, y,z). goroutines运行在相同的地址空间中,所以对共享的内存访问必须同步.sync包提供了基本的同步原语(synchronization primitives),比如互斥锁(mutual exclusion loc

  • R语言学习笔记之lm函数详解

    在使用lm函数做一元线性回归时,发现lm(y~x+1)和lm(y~x)的结果是一致的,一直没找到两者之间的区别,经过大神们的讨论和测试,才发现其中的差别,测试如下: ------------------------------------------------------------- ------------------------------------------------------------- 结果可以发现,两者的结果是一样的,并无区别,但是若改为lm(y~x-1)就能看出+1和

  • R语言学习代码格式一键美化

    目录 RStudio 快捷操作 formatR 包 配合 Shiny 包使用 参考 当写R代码时,很多时候写的代码或者看到的代码缩进都很难统一到标准的格式.这时为了规范化代码,我们需要再代码中一行一行查代码,将其修改成标准的格式. 那么我们有没有一键代码整理的方式或者R包呢? 答案是有的! 下面我们介绍两种方法. RStudio 快捷操作 如果你使用的是RStudio 写代码的话,那么只用全选代码(Ctrl + A),而后输入如下命令: Ctrl + Shift + A 即可简单调整缩进与格式.

随机推荐