golang微服務框架go-zero系列-2:在go-zero中使用jwt-token鑑權實踐

閱讀本文前你需要閱讀

金光燦燦的Gorm V2+適合創業的golang微服務框架go-zero實戰

創建項目

生成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

本文代碼獲取

關注公衆號betaidea 輸入jwt即可獲得 關注公衆號betaidea 輸入gozero即可gozero入門代碼

廣而告之

送福利了uniapp用戶福音來啦! 歷經數十萬用戶考驗,我們的客服系統終於對外提供服務了。 你還在爲商城接入客服煩惱嗎?只需一行代碼,即可接入啦!! 只需一行代碼!!!!

/*kefu.vue*/
<template>
	<view>
		<IdeaKefu :siteid="siteId"  ></IdeaKefu>
	</view>
</template>

<script>
	import IdeaKefu from "@/components/idea-kefu/idea-kefu.vue"
    export default {
		components:{
			IdeaKefu
		},
		data() {
			return {
				siteId:2
			}
		}
    }   

效果槓槓的 客服效果

開發文檔地址 http://kefu.techidea8.com/html/wiki/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章