diff --git a/api/auth.go b/api/auth.go new file mode 100644 index 0000000..220710d --- /dev/null +++ b/api/auth.go @@ -0,0 +1,33 @@ +package api + +import ( + "auth-server/middleware" + "auth-server/model" + "github.com/gin-gonic/gin" +) + +type AuthApi struct{} + +func (AuthApi) Login(c *gin.Context) { + var param model.LoginUser + if err := c.ShouldBindJSON(¶m); err != nil { + middleware.Fail(c, model.ErrParam.AddErr(err)) + return + } + token, err := authService.Login(param) + middleware.Auto(c, err, map[string]string{ + "token": token, + }) + return +} + +func (AuthApi) Register(c *gin.Context) { + var param model.User + if err := c.ShouldBindJSON(¶m); err != nil { + middleware.Fail(c, model.ErrParam.AddErr(err)) + return + } + err := authService.Register(¶m) + middleware.Auto(c, err, nil) + return +} diff --git a/api/init.go b/api/init.go index 94e1b9d..310a4f3 100644 --- a/api/init.go +++ b/api/init.go @@ -6,4 +6,5 @@ import ( var ( userService services.UserService + authService services.AuthService ) diff --git a/api/user.go b/api/user.go index 679cfe4..260ab29 100644 --- a/api/user.go +++ b/api/user.go @@ -14,14 +14,6 @@ type GetUserParam struct { type UserApi struct{} -func (UserApi) CreateUser(c *gin.Context) { - _, _, param := middleware.Validate[any, any, model.User](c) - - errCreate := userService.CreateUser(¶m) - middleware.Auto(c, errCreate, nil) - return -} - func (UserApi) GetUser(c *gin.Context) { params, _, _ := middleware.Validate[GetUserParam, any, any](c) @@ -36,7 +28,9 @@ func (UserApi) GetUser(c *gin.Context) { } func (UserApi) UpdateUser(gin *gin.Context) { + } func (UserApi) DeleteUser(gin *gin.Context) { + } diff --git a/middleware/jwt.go b/middleware/jwt.go index 9a7bd00..920b4ef 100644 --- a/middleware/jwt.go +++ b/middleware/jwt.go @@ -16,8 +16,9 @@ func JWT() gin.HandlerFunc { err = model.ErrParam.AddErr(errors.New("Authorization为空")) } else { _, parseErr := common.ParseToken(token, config.JwtSecret) - err = model.ErrAuthCheckTokenFail.AddErr(parseErr) - + if parseErr != nil { + err = model.ErrAuthToken.AddErr(parseErr) + } } if err.Code != 0 { Fail(c, err) diff --git a/middleware/response.go b/middleware/response.go index 1fe5c5f..34c71a7 100644 --- a/middleware/response.go +++ b/middleware/response.go @@ -27,6 +27,9 @@ func Auto(c *gin.Context, err model.ErrorCode, data interface{}) { if err.Code != 0 { resp.Code = err.Code resp.Msg = err.Msg + if err.Err != nil { + resp.Data = err.Err.Error() + } } else { resp.Data = data } diff --git a/model/errorcode.go b/model/errorcode.go index 12a70f4..744862d 100644 --- a/model/errorcode.go +++ b/model/errorcode.go @@ -38,12 +38,14 @@ func responseErrCode(code int, msg string) ErrorCode { //ERROR_AUTH: "Token错误", var ( - Err = responseErrCode(400, "接口错误") // 通用错误 - ErrParam = responseErrCode(10001, "参数有误") - + Err = responseErrCode(400, "接口错误") // 通用错误 + ErrParam = responseErrCode(10001, "参数有误") + ErrLonginParam = responseErrCode(10001, "用户名或密码错误") ErrSignParam = responseErrCode(10002, "签名参数有误") ErrAuthToken = responseErrCode(10003, "token错误") - ErrAuthCheckTokenFail = responseErrCode(10004, "token鉴权失败") + ErrGenToken = responseErrCode(10004, "token生成错误") + ErrRegisterParam = responseErrCode(10005, "用户名已存在") + ErrAuthCheckTokenFail = responseErrCode(10005, "token鉴权失败") ErrDb = responseErrCode(20003, "数据库错误") // ...... diff --git a/model/user.go b/model/user.go index d4e9717..234dd26 100644 --- a/model/user.go +++ b/model/user.go @@ -16,6 +16,12 @@ type UpdateUser struct { Avatar string `json:"avatar"` } +// LoginUser 用户登陆参数校验 +type LoginUser struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` +} + type GetUserParams struct { Id string `uri:"id" validate:"required"` } diff --git a/proxy/user.go b/proxy/user.go index 00358fb..87d1d9c 100644 --- a/proxy/user.go +++ b/proxy/user.go @@ -2,6 +2,8 @@ package proxy import ( "auth-server/model" + "github.com/pkg/errors" + "gorm.io/gorm" ) type UserProxy struct{} @@ -25,12 +27,29 @@ func (UserProxy) UpdateUser(userId int64, updateUser model.User) (err model.Erro return } -func (UserProxy) GetUser(userId int64) (user *model.User, err model.ErrorCode) { +func (UserProxy) GetUserById(userId int64) (user model.User, found bool, err model.ErrorCode) { db := storageEngine.GetStorageDB() dbErr := db.First(&user, userId).Error - if dbErr != nil { + if errors.Is(dbErr, gorm.ErrRecordNotFound) { + } else if dbErr != nil { + err = model.ErrDb.AddErr(dbErr) + } else { + found = true + } + return +} + +func (UserProxy) GetUserByUsername(userName string) (user model.User, found bool, err model.ErrorCode) { + db := storageEngine.GetStorageDB() + user.Username = userName + dbErr := db.First(&user).Error + if errors.Is(dbErr, gorm.ErrRecordNotFound) { + } else if dbErr != nil { err = model.ErrDb.AddErr(dbErr) + } else { + found = true } + return } diff --git a/router/auth.go b/router/auth.go new file mode 100644 index 0000000..572e81a --- /dev/null +++ b/router/auth.go @@ -0,0 +1,8 @@ +package router + +import "github.com/gin-gonic/gin" + +func authRouter(router *gin.RouterGroup) { + router.POST("/auth/login", apiAuth.Login) + router.POST("/auth/register", apiAuth.Register) +} diff --git a/router/init.go b/router/init.go index 0b13367..af077bb 100644 --- a/router/init.go +++ b/router/init.go @@ -18,7 +18,10 @@ var ( func InitRouter() { engine := gin.New() engine.Use(gin.Recovery()) - + // 登陆认证相关路由 + authRouterGroup := engine.Group("/api/v1") + authRouter(authRouterGroup) + // 用户登陆 userRouterGroup := engine.Group("/api/v1") userRouterGroup.Use(middleware.JWT()) userRouter(userRouterGroup) diff --git a/router/user.go b/router/user.go index c7762e8..a6442c6 100644 --- a/router/user.go +++ b/router/user.go @@ -7,7 +7,6 @@ import ( func userRouter(router *gin.RouterGroup) { // user router.GET("/users/:id", apiUser.GetUser) - router.POST("/users", apiUser.CreateUser) router.PATCH("/users/:id", apiUser.UpdateUser) router.DELETE("/users/:id", apiUser.DeleteUser) } diff --git a/services/auth.go b/services/auth.go new file mode 100644 index 0000000..90b8d2e --- /dev/null +++ b/services/auth.go @@ -0,0 +1,61 @@ +package services + +import ( + "auth-server/common" + "auth-server/config" + "auth-server/model" + "github.com/pkg/errors" +) + +type AuthService struct{} + +var ( + UserNotFoundErr = errors.New("user not found") + UserExistErr = errors.New("user exist") +) + +func (AuthService) Register(user *model.User) (err model.ErrorCode) { + var found bool + _, found, err = proxyUser.GetUserByUsername(user.Username) + if err.Code != 0 { + return + } + if found { + err = model.ErrRegisterParam.AddErr(UserExistErr) + return + } + + // 产生slat + slat := common.GetRandomString(16) + user.Salt = slat + // todo 后续采用加密更强的算法,例如AES + user.Password = common.MD5(slat + user.Password) + err = proxyUser.CreateUser(user) + return +} + +func (AuthService) Login(loginUser model.LoginUser) (token string, err model.ErrorCode) { + var user model.User + var found bool + user, found, err = proxyUser.GetUserByUsername(loginUser.Username) + if err.Code != 0 { + return + } + if !found { + err = model.ErrLonginParam.AddErr(UserNotFoundErr) + return + } + slat := user.Salt + enPassword := common.MD5(slat + loginUser.Password) + if enPassword != user.Password { + err = model.ErrLonginParam + return + } + var genTokenErr error + token, genTokenErr = common.GenerateToken(loginUser.Username, config.JwtSecret, config.JwtExpire, config.ServerName) + if genTokenErr != nil { + err = model.ErrGenToken.AddErr(genTokenErr) + return + } + return +} diff --git a/services/user.go b/services/user.go index 704b034..8fb7317 100644 --- a/services/user.go +++ b/services/user.go @@ -1,22 +1,12 @@ package services import ( - "auth-server/common" "auth-server/model" ) type UserService struct{} -func (UserService) CreateUser(user *model.User) (err model.ErrorCode) { - // 产生slat - slat := common.GetRandomString(16) - // todo 后续采用加密更强的算法,例如AES - user.Password = common.MD5(slat) - err = proxyUser.CreateUser(user) - return -} - -func (UserService) GetUser(userId int64) (user *model.User, err model.ErrorCode) { - user, err = proxyUser.GetUser(userId) +func (UserService) GetUser(userId int64) (user model.User, err model.ErrorCode) { + user, _, err = proxyUser.GetUserById(userId) return }