diff --git a/controller/user.go b/controller/user.go index 3257938..8cf121d 100644 --- a/controller/user.go +++ b/controller/user.go @@ -1,9 +1,11 @@ package controller import ( + "electricity_bill_calc/cache" "electricity_bill_calc/exceptions" "electricity_bill_calc/model" "electricity_bill_calc/response" + "electricity_bill_calc/security" "electricity_bill_calc/service" "errors" "net/http" @@ -22,6 +24,7 @@ func InitializeUserController(router *gin.Engine) { Router: router, } UserController.Router.POST("/login", UserController.Login) + UserController.Router.DELETE("/logout", security.MustAuthenticated, UserController.Logout) } type LoginFormData struct { @@ -59,3 +62,18 @@ func (_UserController) Login(c *gin.Context) { } result.LoginSuccess(session) } + +func (_UserController) Logout(c *gin.Context) { + result := response.NewResult(c) + session, exists := c.Get("session") + if !exists { + result.Success("用户会话已结束。") + return + } + _, err := cache.ClearSession(session.(*model.Session).Token) + if err != nil { + result.Error(http.StatusInternalServerError, err.Error()) + return + } + result.Success("用户已成功登出系统。") +} diff --git a/router/security.go b/security/security.go similarity index 68% rename from router/security.go rename to security/security.go index e3c350d..cb9d4e6 100644 --- a/router/security.go +++ b/security/security.go @@ -1,4 +1,4 @@ -package router +package security import ( "electricity_bill_calc/cache" @@ -25,11 +25,21 @@ func SessionRecovery(c *gin.Context) { c.Next() } +// 用于强制确定用户已经登录了系统,即具有有效的用户会话 +// ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。 +func MustAuthenticated(c *gin.Context) { + session, exists := c.Get("session") + if _, ok := session.(*model.Session); !exists || session == nil || !ok { + c.AbortWithStatus(http.StatusForbidden) + } + c.Next() +} + // 用于对用户会话进行是否企业用户的判断 // ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。 func EnterpriseAuthorize(c *gin.Context) { session, exists := c.Get("session") - if !exists || session.(*model.Session).Type != 0 { + if sess, ok := session.(*model.Session); !exists || !ok || sess.Type != 0 { c.AbortWithStatus(http.StatusForbidden) } c.Next() @@ -39,7 +49,7 @@ func EnterpriseAuthorize(c *gin.Context) { // ! 通过该中间件以后,是可以保证上下文中一定具有用户会话信息的。 func ManagementAuthorize(c *gin.Context) { session, exists := c.Get("session") - if !exists || (session.(*model.Session).Type != 1 && session.(*model.Session).Type != 2) { + if sess, ok := session.(*model.Session); !exists || !ok || (sess.Type != 1 && sess.Type != 2) { c.AbortWithStatus(http.StatusForbidden) } c.Next()