golang 字串分割_Golang 微服務教程(四)
技術標籤:golang 字串分割
Golang 微服務教程(四)
發表於 2018-05-27 | 閱讀次數: | 字數統計: 2,953
原文連結:ewanvalentine.io,翻譯已獲作者 Ewan Valentine 授權。
本文完整程式碼:GitHub
上節引入 user-service 微服務並在 Postgres 中儲存了使用者資料,包括明文密碼。本節將對密碼進行安全的加密處理,並使用唯一的 token 來在各微服務之間識別使用者。
在開始之前,需要手動執行資料庫容器:
12$ docker run -d -p 5432:5432 postgres$ docker run -d -p 27017:27017 mongo
密碼的雜湊處理
安全原則
遵循 ”即使發生資料洩露,密碼等敏感資料也不能被還原“ 的原則,永遠都不要明文儲存使用者的密碼。儘管一直這麼說,但仍有專案是明文儲存,比如以前的 CSDN
雜湊處理
現在更新一下 user-service/handler.go 中處理密碼的邏輯,將密碼進行雜湊處理,再進行儲存:
// user-service/hander.gofunc (h *handler) Create(ctx context.Context, req *pb.User, resp *pb.Response) error {// 雜湊處理使用者輸入的密碼hashedPwd, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)if err != nil {return err}req.Password = string(hashedPwd)if err := h.repo.Create(req); err != nil {return nil}resp.User = reqreturn nil}func (h *handler) Auth(ctx context.Context, req *pb.User, resp *pb.Token) error {u, err := h.repo.GetByEmailAndPassword(req)if err != nil {return err}// 進行密碼驗證if err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(req.Password)); err != nil {return err}t, err := h.tokenService.Encode(u)if err != nil {return err}resp.Token = treturn nil}
只在兩個函式上有改動:在 Create() 中添加了密碼雜湊處理的邏輯,在 Auth() 中用密碼的雜湊值做驗證。重新建立使用者,密碼如下:
現在已經成功結合資料庫完成使用者的密碼驗證,在多個微服務之間進行使用者驗證有很多選擇方案,本文使用 JWT
JWT
簡介
JWT 是 JSON web tokens 的縮寫,是一種類似 OAuth 的分散式安全協議。理解起來很簡單,JWT 協議演算法能為每個使用者生成獨特的雜湊字串,並以此來做校驗和識別。此外,使用者的 metadata(資訊資料)也能作為加密字串的一部分。比如:
1eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
可以看到 token 是被 “.” 分割為三部分的字串:header.payload.signature
header
JWT 頭部包含兩部分:宣告 token 型別、加密 token 的演算法,其進行 base64 加密後作為 token 的第一部分:
{ "typ": "JWT