Go开源宝藏JWT-Go 鉴权 | 中间件 (文末送书嗷~)

Posted 小生凡一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go开源宝藏JWT-Go 鉴权 | 中间件 (文末送书嗷~)相关的知识,希望对你有一定的参考价值。

  • 🎉粉丝福利送书:《Go语言区块链应用开发从入门到精通》
  • 🎉点赞 👍 收藏 ⭐留言 📝 即可参与抽奖送书
  • 🎉下周三(9月22日)晚上20:00将会在【点赞区和评论区】抽一位粉丝送这本书~🙉
  • 🎉详情请看第四点的介绍嗷~✨

本文介绍Go语言的中间件JWT-Go鉴权
JSON Web Token (JWT)是目前最流行的跨域身份验证解决方案
生成token用于前后端交互中验证用户信息


github.com/dgrijalva/jwt-go

1. JWT是什么

我们知道HTTP是无状态的,所以说每一次发送HTTP请求的时候,都必须要带点身份验证的东西,来验证访问者的身份。

传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器以此检查用户是否认证过。

但是这个基于服务器的身份验证存在很多的问题

  1. Sessions : 每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。

  2. Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。

  3. CORS : 当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。

JWT的出现很好地解决了这些问题。

JWT是在服务器身份验证之后,生成一个JSON对象并将其发送回用户。

{
"UserName": "FanOne",
"Role": "Admin",
"Expire": "2021-09-21 20:00:00"
}

之后,当用户与服务器通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。

为了防止用户篡改数据,服务器将在生成对象时添加签名。

服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。

2. JWT的结构

2.1 JWT头

Header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。

{
"alg": "HS256",
"typ": "JWT"
}
  • alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);
  • typ属性表示令牌的类型,JWT令牌统一写为JWT。

2.2 有效载荷

Preload是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择。

Registered claims: 这里有一组预定义的声明,它们不是强制的,但是推荐

  • iss:发行人
  • exp:到期时间
  • sub:主题
  • aud:用户
  • nbf:在此之前不可用
  • iat:发布时间
  • jti:JWT ID用于标识该JWT

Public claims : 可以随意定义。
Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。例如:

{
    "sub": '10086',
    "name": 'FanOne',
    "admin":true
}

2.3签名哈希

签名哈希是对上面两部分数据进行签名,通过指定的算法生成哈希,以确保数据不会被篡改。

签名是用于验证消息在传递过程中有没有被更改,并且,对于使用私钥签名的token,它还可以验证JWT的发送方是否为它所称的发送方。

3. 如何使用JWT-Go

3.1 下载导入

go get github.com/dgrijalva/jwt-go

3.2 使用

  • 定义一个jwtSecret
var jwtSecret = []byte(os.Getenv("JWT_SECRET"))
  • 定义一个Chaims结构体

我这里是把用户的id,用户的name,open_id,authority放进去了加密了,后续解密出来的话,也是这些信息,然后再用这些信息去匹配。

type Claims struct {
	UserID uint `json:"user_id"`  // 自定义的
	UserName  string `json:"user_name"`
	OpenID  string `json:"open_id"`
	Authority int    `json:"authority"`
	jwt.StandardClaims  //官方推荐的
}
  • 签发用户Token
//GenerateToken 签发用户Token
func GenerateToken(userid uint,username, open_id string, authority int) (string, error) {
	nowTime := time.Now()
	expireTime := nowTime.Add(24 * time.Hour)  // Token过期时间
	claims := Claims{
		UserID : userid,
		UserName:  username,
		OpenID:  open_id,
		Authority: authority,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireTime.Unix(),
			Issuer:    "FanOne",
		},
	}
	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := tokenClaims.SignedString(jwtSecret)
	return token, err  // 返回token
}
  • 验证用户Token
func ParseToken(token string) (*Claims, error) {
	tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) { 
		return jwtSecret, nil
	})
	if tokenClaims != nil {
		if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
			return claims, nil
		}
	}
	return nil, err
}

token进行解析,然后就能生成对应的Claims,这个Claims就有上文你放进入的信息。

3.3 例子

Gin框架作为例子

  • 路由初始化的时候,在路由上添加中间件,这样加进去就能验证身份了。
r.Use(middleware.JWT())
  • package middleware 中,我们可以定义这个 middleware,这样就能在执行下面路由的时候,验证这个token是否符合要求了。
func JWT() gin.HandlerFunc {
	return func(c *gin.Context) {
		var code int
		var data interface{}
		code = 200
		token := c.GetHeader("Authorization")
		if token == "" {
			code = 404
		} else {
			claims, err := util.ParseToken(token)
			if err != nil {
				code = e.ErrorAuthCheckTokenFail
			} else if time.Now().Unix() > claims.ExpiresAt {
				code = e.ErrorAuthCheckTokenTimeout
			}
		}
		if code != e.Success {
			c.JSON(200, gin.H{
				"status": code,
				"msg":    e.GetMsg(code),
				"data":   data,
			})
			c.Abort()
			return
		}
		c.Next()
	}
}

4. 福利送书

点赞评论即可参与评论区的送书活动,抽一位小伙伴送书~

【编辑推荐】

  • 理论与实践相结合,每个理论都有对应的实践代码讲解,读者参考源码,完成实例,就可以
    看到实践效果。
  • 每章都配备实训与问答。读者阅读后,能尽快巩固知识点,可以做到举一反三、学以致用。
  • 内容知识体系系统、完备,可以快速帮助读者搭建区块链应用开发知识体系。
  • 易学易懂,零基础读者只要能够理解一些编程上的关键术语就可以阅读本书。Go语言和Solidity是两门独立的开发语言,在本书中都进行了较为细致的讲解,便于读者由浅入深地学习。

【内容简介】

《GO语言区块链应用开发从入门到精通》全面地介绍了Go语言区块链应用工程师所需要的基础知识和各种技术,主要分为基础篇进阶篇实战篇三部分。

全书共7章

  • 其中1~2章为基础篇,介绍Go语言环境安装、基础语法、函数编程、容器编程、面向对象编程、并发编程以及网络编程;
  • 3~5章为进阶篇
  • 第3章介绍区块链基本原理、发展历程、行业应用案例
  • 第4章主要介绍智能合约,包括solidity基础语法,多个经典案例,以及Go语言如何调用智能合约
  • 第5章主要介绍区块链原理的程序化实践,包括Go语言实现Base58编码、P2P网络、PoW共识、区块链组块以及UTXO账户模型实现;
  • 6~7章为实战篇,介绍2个实战项目:
  • 第6章介绍如何实现Go语言版的区块链钱包项目,内容包括助记词生成、私钥存储、Coin交易以及Token交易等内容
  • 第7章介绍如何实现一个版权交易系统,内容包含如何去设计区块链应用系统、后端功能如何与区块链相结合,它既是一个区块链系统应用项目,也是一个Go语言Web服务器项目。

《GO语言区块链应用开发从入门到精通》适合想从事GO语言区块链开发的程序员及GO语言爱好者阅读。

没有中奖的同学可以到这些平台去`康康`嗷~
京东:https://item.jd.com/12858507.html
当当:http://product.dangdang.com/29246989.html

最后

小生凡一,期待你的关注。

以上是关于Go开源宝藏JWT-Go 鉴权 | 中间件 (文末送书嗷~)的主要内容,如果未能解决你的问题,请参考以下文章

Go开源宝藏Golang 爬虫 | 整点新花样

基于gin框架和jwt-go中间件实现小程序用户登陆和token验证

Go开源宝藏十分强大的日志库 logrus

Go开源宝藏十分强大的日志库 logrus

Go开源宝藏Web框架 GIN 专场 (含思维导图) | 持续更新

Go开源宝藏Go语言操作 MongoDB