我們用一個系列來講解從需求到上線、從程式碼到k8s部署、從日誌到監控等各個方面的微服務完整實踐。
整個專案使用了go-zero開發的微服務,基本包含了go-zero以及相關go-zero作者開發的一些中介軟體,所用到的技術棧基本是go-zero專案組的自研元件,基本是go-zero全家桶了。
實戰專案地址:github.com/Mikaelemmmm/go-zero-loo...
1、鑑權服務
1.1 identity-api
identity主要是用來做鑑權服務的,前面我們nginx閘道器的時候有提到。在訪問一個資源的時候,nginx內部會先來identity-api中解析token,identity-api會去請求identity-rpc,所有的驗證與頒發token,統一是在identity-rpc中做的
我們會從header的Authorization中獲取token,從x-Original-Uri獲取訪問的資源路徑
- 如果當前訪問的路由需要登陸:
- token解析失敗:就會返回給前端http401錯誤碼;
- token解析成功:就會將解析出來的userId放入header的x-user中返回給auth模組,auth模組會把header傳遞給對應訪問的服務(usercenter), 這樣我們在usercenter直接就可以拿到該登陸使用者的id了
- 如果當前訪問的路由不需要登陸:
- 前端header中傳遞了token
- 如果token校驗失敗:返回http401;
- 如果token校驗成功:就會將解析出來的userId放入header的x-user中返回給auth模組,auth模組會把header傳遞給對應訪問的服務(usercenter), 這樣我們在usercenter直接就可以拿到該登陸使用者的id了
- 前端header中沒傳遞token:userid 會傳遞 0 給後端服務
- 前端header中傳遞了token
urlNoAuth方法判斷當前資源是否在yml中配置可以不登陸
//當前url是否需要授權驗證
func (l *TokenLogic) urlNoAuth(path string) bool {
for _, val := range l.svcCtx.Config.NoAuthUrls {
if val == path {
return true
}
}
return false
}
isPass方法就是去identity-rpc校驗token,主要也是使用了go-zero的jwt的方法
1.2 identity-rpc
當我們在註冊、登陸成功時候,使用者服務會呼叫identity-rpc生成token,所以我們統一在identity-rpc中頒發、校驗token,這樣就不用每個服務都要寫個jwt去維護。
當identity-api請求進來時候,identity-api自己可以解析出來userid,但是我們要檢驗這個token是否是過期,就要去後端rpc中的redis中去進行二次校驗(當然如果你覺得這裡多一次請求,你可以把這一步放到api裡直接請求redis也可以),經過rpc的validateToken方法校驗
message ValidateTokenReq {
int64 userId = 1;
string token = 2;
}
message ValidateTokenResp {
bool ok = 1;
}
rpc validateToken(ValidateTokenReq) returns(ValidateTokenResp);
校驗之前登陸、註冊等授權時候頒發出去存在redis的token是否正確、過期。
這樣api就可以返回給nginx的auth模組是否失敗,如果失敗auth會直接返回給前端http code 401(所以你們前端應該是先判斷http狀態碼>=400全部異常,再判斷業務錯誤碼) , 如果成功直接訪問後端服務了拿到資料直接返回給前端展示
2、安裝goctl 與 protoc、protoc-gen-go
【注】這個跟鑑權沒什麼關係,只是後面寫程式碼要用到,在這裡最好給安裝了
2.1 安裝goctl
# for Go 1.15 and earlier
GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/goctl@latest
# for Go 1.16 and later
GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest
驗證是否安裝成功
$ goctl --version
Goctl自定義模版template:將專案目錄下的data/goctl資料夾內容copy到 HOME 目錄的 .goctl 中,goctl在生成程式碼時候會優先根據這個模版下內容生成
$ cp -r data/goctl ~/.goctl
2.2 安裝protoc
連結:github.com/protocolbuffers/protobu...
直接找到對應平臺的protoc,我是mac intel晶片,所以直接找到 protoc-3.19.3-osx-x86_64.zip ,解壓出來後進入該目錄下的bin目錄中,將protoc直接copy到你的gopath/bin目錄下即可。
驗證是否安裝成功
$ protoc --version
2.3 安裝protoc-gen-go
$ GOPROXY=https://goproxy.cn/,direct go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
檢視$GOPATH/bin下是否有protoc-gen-go即可
【注】:如果後續在使用goctl生成程式碼時候,遇到以下問題
protoc --proto_path=/Users/seven/Developer/goenv/go-zero-looklook/app/usercenter/cmd/rpc/pb usercenter.proto --go_out=plugins=grpc:/Users/seven/Developer/goenv/go-zero-looklook/app/usercenter/cmd/rpc --go_opt=Musercenter.proto=././pb
goctl: generation error: unsupported plugin protoc-gen-go which installed from the following source:
google.golang.org/protobuf/cmd/protoc-gen-go,
github.com/protocolbuffers/protobuf-go/cmd/protoc-gen-go;
Please replace it by the following command, we recommend to use version before v1.3.5:
go get -u github.com/golang/protobuf/protoc-gen-go
goctl version: 1.3.0 darwin/amd64
直接執行
$ GOPROXY=https://goproxy.cn/,direct go get -u github.com/golang/protobuf/protoc-gen-go
2.4 安裝protoc-gen-go-grpc
$ GOPROXY=https://goproxy.cn/,direct go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
3、總結
總的來說,identity還算是比較簡單的,整個流程如下:
使用者發起請求資源 -> nginx閘道器->匹配到對應服務模組 -> auth模組->identity-api ->identity-rpc -> 使用者請求的資源
專案地址
歡迎使用 go-zero
並 star 支援我們!
微信交流群
關注『微服務實踐』公眾號並點選 交流群 獲取社群群二維碼。
本作品採用《CC 協議》,轉載必須註明作者和本文連結