feat: multi-login(disable) fixed

This commit is contained in:
loveuer 2024-07-19 16:43:12 +08:00
parent 5c852fe559
commit dac1f65fc2
4 changed files with 114 additions and 0 deletions

29
httptest/user.http Normal file
View File

@ -0,0 +1,29 @@
### login
POST http://127.0.0.1:8080/api/user/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "123456"
}
### verify login state
GET http://127.0.0.1:8080/api/user/auth/login
### change self password
POST http://127.0.0.1:8080/api/user/update
Content-Type: application/json
{
"old_password": "123456",
"new_password": "654321@AaBbCc"
}
### relogin with new password
POST http://127.0.0.1:8080/api/user/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "654321@AaBbCc"
}

View File

@ -37,6 +37,8 @@ func initApp(ctx context.Context) *nf.App {
api.Get("/auth/login", auth.NewAuth(), handler.AuthVerify)
api.Post("/auth/logout", auth.NewAuth(), oplog.NewOpLog(ctx), handler.AuthLogout)
api.Post("/update", auth.NewAuth(), handler.UserUpdate)
mng := api.Group("/manage")
mng.Use(auth.NewAuth(), privilege.Verify(
privilege.RelationAnd,

View File

@ -23,6 +23,7 @@ type userController interface {
GetUserByToken(ctx context.Context, token string) (*model.User, error)
CacheUser(ctx context.Context, user *model.User) error
CacheToken(ctx context.Context, token string, user *model.User) error
RmToken(ctx context.Context, token string) error
RmUserCache(ctx context.Context, id uint64) error
DeleteUser(ctx context.Context, id uint64) error
}
@ -118,6 +119,17 @@ func (u uc) CacheToken(ctx context.Context, token string, user *model.User) erro
key := fmt.Sprintf("%s:user:token:%s", opt.CachePrefix, strs[2])
return cache.Client.SetEx(tool.Timeout(3), key, user.Id, opt.TokenTimeout)
}
func (u uc) RmToken(ctx context.Context, token string) error {
strs := strings.Split(token, ".")
if len(strs) != 3 {
return fmt.Errorf("controller.CacheToken: jwt token invalid")
}
key := fmt.Sprintf("%s:user:token:%s", opt.CachePrefix, strs[2])
return cache.Client.Del(tool.Timeout(3), key)
}
func (u uc) RmUserCache(ctx context.Context, id uint64) error {
key := fmt.Sprintf("%s:user:id:%d", opt.CachePrefix, id)
return cache.Client.Del(tool.Timeout(3), key)

View File

@ -76,11 +76,18 @@ func AuthLogin(c *nf.Ctx) error {
bs []byte
)
// 获取之前的 token
if bs, err = cache.Client.Get(tool.Timeout(3), last); err == nil {
key := fmt.Sprintf("%s:user:token:%s", opt.CachePrefix, string(bs))
_ = cache.Client.Del(tool.Timeout(3), key)
}
// 删掉之前的 token
if len(bs) > 0 {
_ = controller.UserController.RmToken(c.Context(), string(bs))
}
// 将当前的 token 存入 last_token
if err = cache.Client.Set(tool.Timeout(3), last, token); err != nil {
return resp.Resp500(c, err.Error())
}
@ -129,6 +136,70 @@ func AuthLogout(c *nf.Ctx) error {
return resp.Resp200(c, nil)
}
func UserUpdate(c *nf.Ctx) error {
type Req struct {
OldPassword string `json:"old_password"`
NewPassword string `json:"new_password"`
}
type Model struct {
Password string `gorm:"column:password"`
}
var (
ok bool
err error
req = new(Req)
user *model.User
m = new(Model)
)
if user, ok = c.Locals("user").(*model.User); !ok {
return resp.Resp401(c, nil)
}
if err = c.BodyParser(req); err != nil {
return resp.Resp400(c, err)
}
if req.OldPassword == "" || req.NewPassword == "" {
return resp.Resp400(c, req)
}
if err = tool.CheckPassword(req.NewPassword); err != nil {
return resp.Resp400(c, req, err.Error())
}
if err = db.New(tool.Timeout(3)).
Select("password").
Model(&model.User{}).
Where("username = ?", user.Username).
Where("deleted_at = 0").
Take(m).
Error; err != nil {
return resp.Resp500(c, err.Error())
}
if !tool.ComparePassword(req.OldPassword, m.Password) {
return resp.Resp400(c, nil, "原密码错误")
}
if err = db.New(tool.Timeout(5)).
Model(&model.User{}).
Where("id = ?", user.Id).
Update("password", tool.NewPassword(req.NewPassword)).
Error; err != nil {
return resp.Resp500(c, err.Error())
}
_ = controller.UserController.RmUserCache(c.Context(), user.Id)
// todo delete token
c.SetHeader("Set-Cookie", fmt.Sprintf("%s=;Path=/", opt.CookieName))
return resp.Resp200(c, nil, "修改成功, 请重新登录")
}
func ManageUserList(c *nf.Ctx) error {
type Req struct {
Page int `query:"page"`