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服务重复上面的步骤…