如何在go-zero中使用jwt-token鉴权实践

本篇文章给大家分享的是有关如何在go-zero中使用jwt-token鉴权实践,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

为偃师等地区用户提供了全套网页设计制作服务,及偃师网站建设行业解决方案。主营业务为成都网站设计、网站制作、偃师网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

创建项目

生成go.mod文件

以如下指令创建项目

mkdir jwttoken
cd jwttoken
go mod init  jwttoken

定义user.api

本文设计API如下 |描述|格式|方法|参数|返回|是否需要鉴权| |----|----|----|----|----|----| |用户登录|/open/authorization|post|mobile:手机号,passwd:密码,code:图片验证码|id:用户ID,token:用户token|否| |更新用户信息|/user/update|post|mobile:用户手机号|token:用户新的token|是|

根据以上描述,书写api的模板文件如下

type (
	UserOptReq struct {
		mobile string `form:"mobile"`
		passwd string `form:"passwd"`
		code   string `form:"code,optional"`
	}

	UserOptResp struct {
		id    uint   `json:"id"`
		token string `json:"token"`
	}
	//修改
	UserUpdateReq struct {
		id     uint   `form:"id"`
		mobile string `form:"mobile,optional"`
	}
)

service user-api {
	@server(
		handler: authorizationHandler
		folder: open
	)
	post /open/authorization(UserOptReq) returns(UserOptResp)

	@server(
		handler: edituserHandler
		folder: user
	)
	post /user/update(UserUpdateReq) returns(UserOptResp)
	
}

注意

  • 一个文件里面只能有一个service

  • 工具最后会以type里面模型为样板生成各种结构体,所以参数和结构体保持一致即可

  • 如果我们需要分文件夹管理业务, 可以用folder属性来定义

生成代码

采用如下指令生成代码

goctl api  go   -api   user.api   -dir  .

运行一下

go run open.go

测试一下

curl http://127.0.0.1:8888/open/authorization -X POST -d "mobile=15367151352&passwd=123rte&code=asasa"\"passwd\":\"testpwd\",\"code\":\"asdf\"}
{"id":0,"token":""}

中间件实现鉴权

handler下新建auth.go文件,关键代码如下

//鉴权白名单,在这里面的是不需要鉴权的
var whiteList []string = []string{
	"/open/",
}

//鉴权中间件
func Auth(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("X-Middleware", "auth")
		uri := r.RequestURI
		//默认不在
		isInWhiteList := false
		//判断请求是否包含白名单中的元素
		for _, v := range whiteList {
			if strings.Contains(uri, v) {
				isInWhiteList = true
			}
		}
		//如果爱白名单里面直接通过
		if isInWhiteList {
			next(w, r)
			return
		}
		//否则获取前端header 里面的X-Token字段,这个就是token	
		token := r.Header.Get("X-Token")
		//工具类见util\jwttoken.go
		_, err := utils.DecodeJwtToken(token)
		//如果有错直接返回error
		if err != nil {
			httpx.Error(w, err)
			return
		}
		//没报错就继续
		next(w, r)
	}
}

routers.go中添加一行代码

func RegisterHandlers(engine *rest.Server, serverCtx *svc.ServiceContext) {
	//添加这行代码
	engine.Use(Auth)
	///。。
}	

生成jwttoken

logic\open\authorizationlogic.go中实现jwttoken的获取

func (l *AuthorizationLogic) Authorization(req types.UserOptReq) (*types.UserOptResp, error) {
	//这个是生成jwttoken的工具类
	token, err := utils.EncodeJwtToken(map[string]interface{}{
		"role": "kefu",
		"id":   "10086",
	})
	return &types.UserOptResp{
		Token: token,
	}, err
}

测试

不携带token时访问

>curl http://127.0.0.1:8888/user/update -X POST -d "mobile=15367151352&id=123"
鉴权失败,缺少鉴权参数

获取token

>curl http://127.0.0.1:8081/open/authorization -X POST -d "mobile=15367151352&passwd=123rte&code=asasa"
{"id":1599063149,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTkzMjIzNDksImlkIjoiMTUzNjcxNTEzNTIifQ.jcdg3c2rdigPO5ZTxcDilVGERAuMIdY9BUmMNX3ZA9c"}

携带token时访问

>curl http://127.0.0.1:8888/user/update -X POST -H "X-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTkzMjIzNDksImlkIjoiMTUzNjcxNTEzNTIifQ.jcdg3c2rdigPO5ZTxcDilVGERAuMIdY9BUmMNX3ZA9c" -d "mobile=15367151352&id=123"
# 请求成功
{"id":123,"token":""}

携带错误的token时访问

>curl http://127.0.0.1:8888/user/update -X POST -H "X-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1OTkzMjIzNDksImlkIjoiMTUzNjcxNTEzNTIifQ.jcdg3c2rdigPO5ZTxcDilVGERAuMIdY9BUmMNX3ZA9c0000" -d "mobile=15367151352&id=123"
# 返回签名无效
signature is invalid

以上就是如何在go-zero中使用jwt-token鉴权实践,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。


文章名称:如何在go-zero中使用jwt-token鉴权实践
链接地址:http://ybzwz.com/article/iheeod.html