go-zero docker-compose 搭建課件服務(六):完善jwt鑑權和返回結構

slowquery發表於2022-08-29

0、轉載

go-zero docker-compose 搭建課件服務(六):完善jwt鑑權和返回結構

0.1原始碼地址

github.com/liuyuede123/go-zero-cou...

1、使用者服務登入介面生成jwt token

user/api/etc/user.yaml中增加用於生成jwt的secret和過期時間

...

Auth:
  AccessSecret: 38f9c7af24ff11edb92900163e30ef81
  AccessExpire: 86400

user/api/internal/config/config.go增加配置引數

...

Auth struct {
        AccessSecret string
        AccessExpire int64
}

在之前編寫的登入邏輯中增加獲取token的方法,並修改登入邏輯

...

func (l *UserLoginLogic) UserLogin(req *types.LoginRequest) (resp *types.LoginResponse, err error) {
    login, err := l.svcCtx.UserRpc.Login(l.ctx, &userclient.LoginRequest{
        LoginName: req.LoginName,
        Password:  req.Password,
    })
    if err != nil {
        return nil, err
    }

    now := time.Now().Unix()
    login.Token, err = l.getJwtToken(l.svcCtx.Config.Auth.AccessSecret, now, l.svcCtx.Config.Auth.AccessExpire, int64(login.Id))
    if err != nil {
        return nil, status.Error(5000, err.Error())
    }
    return &types.LoginResponse{
        Id:    login.Id,
        Token: login.Token,
    }, nil
}

func (l *UserLoginLogic) getJwtToken(secretKey string, iat, seconds, userId int64) (string, error) {
    claims := make(jwt.MapClaims)
    claims["exp"] = iat + seconds
    claims["iat"] = iat
    claims["userId"] = userId
    token := jwt.New(jwt.SigningMethodHS256)
    token.Claims = claims
    return token.SignedString([]byte(secretKey))
}

2、使用者密碼加密

user/rpc/internal/logic/registerlogic.go修改程式碼加密密碼

...

func (l *RegisterLogic) Register(in *user.RegisterRequest) (*user.RegisterResponse, error) {
    _, err := l.svcCtx.UserModel.FindOneByLoginName(l.ctx, in.LoginName)
    if err == nil {
        return nil, status.Error(5000, "登入名已存在")
    }

    if err != model.ErrNotFound {
        return nil, status.Error(500, err.Error())
    }

    pwd, err := bcrypt.GenerateFromPassword([]byte(in.Password), bcrypt.DefaultCost)
    if err != nil {
        return nil, status.Error(500, err.Error())
    }
    newUser := model.User{
        LoginName: in.LoginName,
        Username:  in.Username,
        Sex:       in.Sex,
        Password:  string(pwd),
    }
    _, err = l.svcCtx.UserModel.Insert(l.ctx, &newUser)
    if err != nil {
        return nil, status.Error(500, err.Error())
    }

    return &user.RegisterResponse{}, nil
}

user/rpc/internal/logic/loginlogic.go 登入邏輯修改密碼驗證

...

func (l *LoginLogic) Login(in *user.LoginRequest) (*user.LoginResponse, error) {
    userInfo, err := l.svcCtx.UserModel.FindOneByLoginName(l.ctx, in.LoginName)
    if err == model.ErrNotFound {
        return nil, status.Error(5000, "使用者不存在")
    }
    if err != nil {
        return nil, status.Error(500, err.Error())
    }

    err = bcrypt.CompareHashAndPassword([]byte(userInfo.Password), []byte(in.Password))
    if err != nil {
        return nil, status.Error(5000, "密碼錯誤")
    }

    return &user.LoginResponse{
        Id:    userInfo.Id,
        Token: "a.b.c",
    }, nil
}

3、其他介面增加鑑權中介軟體

修改courseware/api/courseware.api增加鑑權中介軟體

...

@server (
    jwt : Auth
)
service courseware {
    @handler coursewareAdd
    post /api/courseware/add (AddRequest) returns (AddResponse)

    @handler coursewareUpdate
    post /api/courseware/update (UpdateRequest) returns (UpdateResponse)

    @handler coursewareGet
    post /api/courseware/get (GetRequest) returns (GetResponse)

    @handler coursewareDelete
    post /api/courseware/delete (DeleteRequest) returns (DeleteResponse)

courseware/api/etc/courseware.yaml課件api增加auth配置

...

Auth:
  AccessSecret: 38f9c7af24ff11edb92900163e30ef81
  AccessExpire: 86400

courseware/api/internal/config/config.go增加auth配置

Auth struct {
        AccessSecret string
        AccessExpire int64
}

到courseware/api/目錄下重新生成路由檔案

goctl api go -api courseware.api -dir . -style gozero

使用者服務獲取使用者資訊介面需要增加許可權校驗

修改user/api/user.api增加鑑權中介軟體

...

service user {
    @handler userLogin
    post /api/user/login (LoginRequest) returns (LoginResponse)

    @handler userRegister
    post /api/user/register (RegisterRequest) returns (RegisterResponse)
}

@server (
    jwt : Auth
)
service user {

    @handler userInfo
    post /api/user/userInfo (UserInfoRequest) returns (UserInfoResponse)
}

第一步已經生成auth相關配置不需要重新設定,到user/api/目錄下更新路由

goctl api go -api user.api -dir . -style gozero

4、返回結構最佳化

課件api層新增courseware/api/response/response.go

package response

import (
    "github.com/zeromicro/go-zero/rest/httpx"
    "net/http"
)

type Body struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data,omitempty"`
}

func Response(w http.ResponseWriter, resp interface{}, err error) {
    var body Body
    if err != nil {
        body.Code = 5000
        body.Message = err.Error()
        body.Data = nil
    } else {
        body.Code = 0
        body.Message = "OK"
        body.Data = resp
    }
    httpx.OkJson(w, body)
}

handler中修改返回結構

修改前

...

if err != nil {
            httpx.Error(w, err)
        } else {
            httpx.OkJson(w, resp)
        }

修改後

response.Response(w, resp, err)

使用者api服務重複上面的步驟…

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章