golang项目中加入token方式

 更新时间:2026年06月25日 14:57:47   作者:忍界英雄  
这段文章详细介绍了token在系统安全中的应用,包括token的概念、作用及部署方法,强调了token在保障系统安全中的重要性,文章还提供了具体的代码示例,指导如何在Gin项目中实现token验证机制

什么是token

"token"指的是一种用于验证用户身份或授权访问的凭证。这种类型的token在进行网络身份验证时非常常见,例如,在网站登录时生成的身份验证令牌或OAuth(开放授权)协议中用于授权访问资源的访问令牌。

token一般在用户登录成功时由服务器端生成并随数据一同发送给客户端,由客户端存储token,并在再次发送请求时,在请求头中带上token并发送给客户端。

为什么要加入token

试想一下,如果没有token,任何游客都可以随意的访问系统内的各个接口,那么系统的安全性就没有办法得到保障。恶意用户可以利用管理员权限,随意调用相关接口以获取系统内部信息,系统用户信息,或者对系统端口进行网络攻击。

加入token以后,我们通过使用token进行授权可以实现细粒度的权限控制,因为每个token可以包含特定的访问权限。这样可以确保用户只能访问其被授权的资源,从而增强系统的安全性。

如何在go项目中部署token

那么,怎么在我们的go项目中部署token呢,当然是利用成熟的go包。

首先在项目中需要导入JWT(JSON Web Token)数据包

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

然后编写token生成函数

func GenerateJwt() string {
	log := logrus.WithFields(logrus.Fields{
		"func": "GenerateJwt",
	})
	token := jwt.New(jwt.SigningMethodHS256)
    //jwt.New()创建一个新的JWT对象,使用HS256算法对其进行签名

	claims := make(jwt.MapClaims)
	claims["exp"] = time.Now().Add(time.Hour * time.Duration(common.TokenDuration)).Unix()
	claims["iat"] = time.Now().Unix()
	token.Claims = claims
    //创建JWT(JSON Web Token)的载荷部分,并声明token的过期事件和创建时间。

	tokenString, err := token.SignedString([]byte(common.SecretKey))
    //使用密钥对jwt进行签名,并生成toekn字符串
	if err != nil {
		log.Errorf("GenerateJwt err:%v", err)
	}

	return tokenString
}

在函数中,使用log记录函数中的错误信息,如果没有记录日志的需求,log也可以省略。

函数中claims用于存储jwt的荷载信息,其中的exp和iat为jwt的标准声明,表示token的过期时间,和创建时间。

  • common.TokenDuration是一个整形常量,用于设定token存在时间。
  • common.SecretKey为一个字符串常量,自己设定,表示对数据进行加密时用到的密钥。

由于common.SecretKey只有设定者知道,除系统外,恶意用户将无法对token进行解密。

编写完token函数,在用户登录成功时,应该将token返回给用户,用户以token作为自身身份凭证。

	if user.Phone != "" {
		if judge := sql.IfadminPhone(c, &user, log); judge {
			token := gentoken.GenerateJwt()//token生成函数
			c.JSON(200, gin.H{"message": "Login successful", "token": token})  //返回给用户token
			return
		}}

我们使用postman验证token是否生成成功。

{
    "message": "Login successful",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDkyNTkzMDQsImlhdCI6MTcwOTI1NTcwNH0.zc3DznaTQxOZMqlloS2dSAVC-AgbrE9FId2TQE03_uQ"
}

可以看到,登录成功时服务器成功向用户访问了token

如何验证token

那么,如何验证token信息呢?除了登录和注册功能外,其他所有接口均需验证token信息。

我在项目中使用到了gin框架,使用gin框架的中间件,可以方便的完成这个功能。

func Router() *gin.Engine {
	r := gin.Default()
	r.POST("/user/login", service.Login)
	r.POST("/user/register", service.Register)

	auth := r.Group("/")
	auth.Use(gentoken.AuthMiddleware())
	{
		auth.GET("/index", service.GetIndex)
		auth.GET("/user/getUserList", service.GetUserList)
		auth.GET("/user/findUserByName", service.FindUserByName)
		auth.GET("/user/delete", service.DeleteUser) //删除指定用户名的用户
		auth.POST("/user/update", service.UpdateUser)

		//发送消息
		auth.GET("/user/sendUserMsg", service.SendUserMsg)
		auth.GET("/user/sendMsg", service.SendMsg)
	}}

通过r.Group将除登录注册外的所有功能设置为一个auth组,并为该组成员添加中间件gentoken.AuthMiddleware()函数。

这样,所有要访问auth组的请求都需要经过AuthMiddleware()函数验证后才能获取到服务。

在AuthMiddleware()函数中我们添加验证token的请求:

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		tokenString := c.GetHeader("Authorization")
		if tokenString == "" {
			c.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			return []byte(common.SecretKey), nil
		})

		if err == nil && token.Valid {
			c.Next()
		} else {
			c.AbortWithStatus(http.StatusUnauthorized)
		}
	}
}

其中common.SecretKey为加密时使用的密钥,此时要通过jwt.Parse()函数将其解密。

通过token.Valid验证token是否过期,是否为系统签发。

好了,现在token验证机制已经完成。

验证

我们首先用postman发送不带token的请求到系统服务。

发现系统无返回值。

在头部带上token后:

成功使用系统功能获取到用户信息。

好了,现在你可以在自己的项目里部署一个简单的token来进行用户身份验证啦!!

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • go语言通过zlib压缩数据的方法

    go语言通过zlib压缩数据的方法

    这篇文章主要介绍了go语言通过zlib压缩数据的方法,实例分析了Go语言中zlib的使用技巧,需要的朋友可以参考下
    2015-03-03
  • golang 实现 pdf 转高清晰度 jpeg的处理方法

    golang 实现 pdf 转高清晰度 jpeg的处理方法

    这篇文章主要介绍了golang 实现 pdf 转高清晰度 jpeg,下面主要介绍Golang 代码使用方法及Golang PDF转JPEG的详细代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • 使用Go语言实现敏感词过滤功能

    使用Go语言实现敏感词过滤功能

    敏感词过滤,算是一个比较常见的功能,尤其是在内容、社交类应用中更是如此,本文介绍如何使用Go语言实现简单的敏感词过滤功能,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • 关于go-micro与其它gRPC框架之间的通信问题及解决方法

    关于go-micro与其它gRPC框架之间的通信问题及解决方法

    在之前的文章中分别介绍了使用gRPC官方插件和go-micro插件开发gRPC应用程序的方式,都能正常走通。不过当两者混合使用的时候,互相访问就成了问题,下面通过本文给大家讲解下go-micro与gRPC框架通信问题,一起看看吧
    2022-04-04
  • Golang使用ttl机制保存内存数据方法详解

    Golang使用ttl机制保存内存数据方法详解

    ttl(time-to-live) 数据存活时间,我们这里指数据在内存中保存一段时间,超过期限则不能被读取到,与Redis的ttl机制类似。本文仅实现ttl部分,不考虑序列化和反序列化
    2023-03-03
  • Go语言中的自定义函数类型的实现

    Go语言中的自定义函数类型的实现

    在Go语言中,函数类型是一种将函数作为值的数据类型,本文主要介绍了Go语言中的自定义函数类型,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • go语言读取json并下载高清妹子图片

    go语言读取json并下载高清妹子图片

    前面我们介绍了使用python下载高清妹子图,作为程序猿,我们当然不能只会一种语言,今天我们就来使用go语言来读取API来下载妹子图吧,有需要的宅男们可以参考下。
    2015-03-03
  • Go语言开发浏览器视频流rtsp转webrtc播放

    Go语言开发浏览器视频流rtsp转webrtc播放

    这篇文章主要为大家介绍了Go语言开发浏览器视频流rtsp转webrtc播放的过程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • Go 第三方库之类型转换问题

    Go 第三方库之类型转换问题

    今天给大家介绍一个第三方库,专门处理类型转换的问题。对Go 第三方库之类型转换问题感兴趣的朋友跟随小编一起看看吧
    2021-08-08
  • go语言使用Casbin实现角色的权限控制

    go语言使用Casbin实现角色的权限控制

    Casbin是用于Golang项目的功能强大且高效的开源访问控制库。本文主要介绍了go语言使用Casbin实现角色的权限控制,感兴趣的可以了解下
    2021-06-06

最新评论