auth.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package handler
  2. import (
  3. "encoding/base64"
  4. "go-admin/app/admin/models"
  5. "go-admin/common"
  6. "net/http"
  7. "os"
  8. "go-admin/common/global"
  9. "go-admin/common/utils"
  10. "github.com/gin-gonic/gin"
  11. "github.com/go-admin-team/go-admin-core/sdk"
  12. "github.com/go-admin-team/go-admin-core/sdk/api"
  13. "github.com/go-admin-team/go-admin-core/sdk/config"
  14. "github.com/go-admin-team/go-admin-core/sdk/pkg"
  15. "github.com/go-admin-team/go-admin-core/sdk/pkg/captcha"
  16. jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth"
  17. "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth/user"
  18. "github.com/go-admin-team/go-admin-core/sdk/pkg/response"
  19. "github.com/mssola/user_agent"
  20. "github.com/pkg/errors"
  21. )
  22. func PayloadFunc(data interface{}) jwt.MapClaims {
  23. if v, ok := data.(map[string]interface{}); ok {
  24. u, _ := v["user"].(SysUser)
  25. r, _ := v["role"].(SysRole)
  26. return jwt.MapClaims{
  27. jwt.IdentityKey: u.UserId,
  28. jwt.RoleIdKey: r.RoleId,
  29. jwt.RoleKey: r.RoleKey,
  30. jwt.NiceKey: u.Username,
  31. jwt.DataScopeKey: r.DataScope,
  32. jwt.RoleNameKey: r.RoleName,
  33. }
  34. }
  35. return jwt.MapClaims{}
  36. }
  37. func IdentityHandler(c *gin.Context) interface{} {
  38. claims := jwt.ExtractClaims(c)
  39. return map[string]interface{}{
  40. "IdentityKey": claims["identity"],
  41. "UserName": claims["nice"],
  42. "RoleKey": claims["rolekey"],
  43. "UserId": claims["identity"],
  44. "RoleIds": claims["roleid"],
  45. "DataScope": claims["datascope"],
  46. }
  47. }
  48. // Authenticator 获取token
  49. // @Summary 登陆
  50. // @Description 获取token
  51. // @Description LoginHandler can be used by clients to get a jwt token.
  52. // @Description Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
  53. // @Description Reply will be of the form {"token": "TOKEN"}.
  54. // @Description dev mode:It should be noted that all fields cannot be empty, and a value of 0 can be passed in addition to the account password
  55. // @Description 注意:开发模式:需要注意全部字段不能为空,账号密码外可以传入0值
  56. // @Tags 登陆
  57. // @Accept application/json
  58. // @Product application/json
  59. // @Param account body Login true "account"
  60. // @Success 200 {string} string "{"code": 200, "expire": "2019-08-07T12:45:48+08:00", "token": ".eyJleHAiOjE1NjUxNTMxNDgsImlkIjoiYWRtaW4iLCJvcmlnX2lhdCI6MTU2NTE0OTU0OH0.-zvzHvbg0A" }"
  61. // @Router /api/v1/login [post]
  62. func Authenticator(c *gin.Context) (interface{}, error) {
  63. log := api.GetRequestLogger(c)
  64. db, err := pkg.GetOrm(c)
  65. if err != nil {
  66. log.Errorf("get db error, %s", err.Error())
  67. response.Error(c, 500, err, "数据库连接获取失败")
  68. return nil, jwt.ErrFailedAuthentication
  69. }
  70. var loginVals Login
  71. var status = "2"
  72. var msg = "登录成功"
  73. var username = ""
  74. defer func() {
  75. LoginLogToDB(c, status, msg, username)
  76. }()
  77. if err = c.ShouldBind(&loginVals); err != nil {
  78. username = loginVals.Username
  79. msg = "数据解析失败"
  80. status = "1"
  81. return nil, jwt.ErrMissingLoginValues
  82. }
  83. if config.ApplicationConfig.Mode != "dev" {
  84. if !captcha.Verify(loginVals.UUID, loginVals.Code, true) {
  85. username = loginVals.Username
  86. msg = "验证码错误"
  87. status = "1"
  88. return nil, jwt.ErrInvalidVerificationode
  89. }
  90. }
  91. // rsa 解密密码
  92. privkey, err := os.ReadFile("id_rsa")
  93. if err != nil {
  94. return nil, errors.Wrap(err, "获取privkey失败")
  95. }
  96. passBytes, err := base64.StdEncoding.DecodeString(loginVals.Password)
  97. if err != nil {
  98. return nil, errors.Wrap(err, "base64解密失败")
  99. }
  100. pass, err := utils.RsaDecrypt(passBytes, privkey)
  101. if err != nil {
  102. return nil, errors.Wrap(err, "rsa解密失败")
  103. }
  104. loginVals.Password = string(pass)
  105. user, role, e := loginVals.GetUser(db)
  106. if e == nil {
  107. username = loginVals.Username
  108. return map[string]interface{}{"user": user, "role": role}, nil
  109. } else {
  110. msg = "登录失败"
  111. status = "1"
  112. log.Warnf("%s login failed!", loginVals.Username)
  113. }
  114. return nil, jwt.ErrFailedAuthentication
  115. }
  116. // LoginLogToDB Write log to database
  117. func LoginLogToDB(c *gin.Context, status string, msg string, username string) {
  118. if !config.LoggerConfig.EnabledDB {
  119. return
  120. }
  121. log := api.GetRequestLogger(c)
  122. l := make(map[string]interface{})
  123. ua := user_agent.New(c.Request.UserAgent())
  124. l["ipaddr"] = common.GetClientIP(c)
  125. l["loginLocation"] = "" // pkg.GetLocation(common.GetClientIP(c),gaConfig.ExtConfig.AMap.Key)
  126. l["loginTime"] = pkg.GetCurrentTime()
  127. l["status"] = status
  128. l["remark"] = c.Request.UserAgent()
  129. browserName, browserVersion := ua.Browser()
  130. l["browser"] = browserName + " " + browserVersion
  131. l["os"] = ua.OS()
  132. l["platform"] = ua.Platform()
  133. l["username"] = username
  134. l["msg"] = msg
  135. q := sdk.Runtime.GetMemoryQueue(c.Request.Host)
  136. message, err := sdk.Runtime.GetStreamMessage("", global.LoginLog, l)
  137. if err != nil {
  138. log.Errorf("GetStreamMessage error, %s", err.Error())
  139. //日志报错错误,不中断请求
  140. } else {
  141. err = q.Append(message)
  142. if err != nil {
  143. log.Errorf("Append message error, %s", err.Error())
  144. }
  145. }
  146. }
  147. // LogOut
  148. // @Summary 退出登录
  149. // @Description 获取token
  150. // LoginHandler can be used by clients to get a jwt token.
  151. // Reply will be of the form {"token": "TOKEN"}.
  152. // @Accept application/json
  153. // @Product application/json
  154. // @Success 200 {string} string "{"code": 200, "msg": "成功退出系统" }"
  155. // @Router /logout [post]
  156. // @Security Bearer
  157. func LogOut(c *gin.Context) {
  158. LoginLogToDB(c, "2", "退出成功", user.GetUserName(c))
  159. c.JSON(http.StatusOK, gin.H{
  160. "code": 200,
  161. "msg": "退出成功",
  162. })
  163. }
  164. func Authorizator(data interface{}, c *gin.Context) bool {
  165. if v, ok := data.(map[string]interface{}); ok {
  166. u, _ := v["user"].(models.SysUser)
  167. r, _ := v["role"].(models.SysRole)
  168. c.Set("role", r.RoleName)
  169. c.Set("roleIds", r.RoleId)
  170. c.Set("userId", u.UserId)
  171. c.Set("userName", u.Username)
  172. c.Set("dataScope", r.DataScope)
  173. return true
  174. }
  175. return false
  176. }
  177. func Unauthorized(c *gin.Context, code int, message string) {
  178. c.JSON(http.StatusOK, gin.H{
  179. "code": code,
  180. "msg": message,
  181. })
  182. }