auth.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. package handler
  2. import (
  3. "cold-delivery/app/admin/model"
  4. "cold-delivery/common"
  5. "cold-delivery/common/global"
  6. "errors"
  7. "fmt"
  8. "github.com/gin-gonic/gin"
  9. "github.com/go-redis/redis/v7"
  10. "github.com/go-sql-driver/mysql"
  11. "github.com/mssola/user_agent"
  12. "gogs.baozhida.cn/zoie/OAuth-core/api"
  13. "gogs.baozhida.cn/zoie/OAuth-core/pkg"
  14. jwt "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth"
  15. "gogs.baozhida.cn/zoie/OAuth-core/pkg/jwtauth/user"
  16. "gogs.baozhida.cn/zoie/OAuth-core/pkg/response"
  17. "gogs.baozhida.cn/zoie/OAuth-core/sdk"
  18. "gogs.baozhida.cn/zoie/OAuth-core/sdk/config"
  19. "gorm.io/gorm"
  20. "net/http"
  21. "strings"
  22. )
  23. func PayloadFunc(data interface{}) jwt.MapClaims {
  24. if v, ok := data.(map[string]interface{}); ok {
  25. u, _ := v["user"].(SysUser)
  26. r, _ := v["role"].(SysRole)
  27. d, _ := v["dept"].(SysDept)
  28. p, _ := v["post"].(SysPost)
  29. single, _ := v["single"].(bool)
  30. return jwt.MapClaims{
  31. jwt.UUIDKey: u.Uuid,
  32. jwt.IdentityKey: u.Id,
  33. jwt.RoleIdKey: r.Id,
  34. jwt.RoleKey: r.RoleKey,
  35. jwt.UserNameKey: u.Username,
  36. jwt.DataScopeKey: r.DataScope,
  37. jwt.RoleNameKey: r.Name,
  38. jwt.SingleKey: single,
  39. jwt.DeptIdKey: u.DeptId,
  40. jwt.DeptNameKey: d.DeptName,
  41. "postId": u.PostId,
  42. "postCode": p.PostCode,
  43. }
  44. }
  45. return jwt.MapClaims{}
  46. }
  47. func IdentityHandler(c *gin.Context) interface{} {
  48. claims := jwt.ExtractClaims(c)
  49. return map[string]interface{}{
  50. "UUIDKey": claims["uuid"],
  51. "IdentityKey": claims["identity"],
  52. "UserName": claims["username"],
  53. "RoleName": claims["roleName"],
  54. "RoleKey": claims["roleKey"],
  55. "Id": claims["identity"],
  56. "RoleId": claims["roleId"],
  57. "DataScope": claims["dataScope"],
  58. "single": claims["single"],
  59. "DeptId": claims["deptId"],
  60. "DeptName": claims["deptName"],
  61. "PostId": claims["postId"],
  62. "PostCode": claims["postCode"],
  63. }
  64. }
  65. // Authenticator 登录认证
  66. // Update 登录认证
  67. // @Summary 登录认证
  68. // @Description 登录认证
  69. // @Tags 登录
  70. // @Accept application/json
  71. // @Product application/json
  72. // @Param data body Login true "body"
  73. // @Success 200 {object} response.Response "{"code": 200, "data": [...]}"
  74. // @Router /api/login [post]
  75. func Authenticator(c *gin.Context) (interface{}, error) {
  76. log := api.GetRequestLogger(c)
  77. ormDB, err := pkg.GetOrm(c)
  78. if err != nil {
  79. log.Errorf("get db error, %s", err.Error())
  80. response.Error(c, 500, err, "数据库连接获取失败")
  81. return nil, jwt.ErrFailedAuthentication
  82. }
  83. var loginVals Login
  84. var status = "2"
  85. var msg = "登录成功"
  86. var username = ""
  87. defer func() {
  88. LoginLogToDB(c, status, msg, username)
  89. }()
  90. if err = c.ShouldBind(&loginVals); err != nil {
  91. username = loginVals.Username
  92. msg = "数据解析失败"
  93. status = "1"
  94. return nil, jwt.ErrFailedAuthentication
  95. }
  96. //if config.ApplicationConfig.Mode != "dev" {
  97. // if !captcha.Verify(loginVals.UUID, loginVals.Code, true) {
  98. // username = loginVals.Username
  99. // msg = "验证码错误"
  100. // status = "1"
  101. //
  102. // return nil, jwt.ErrInvalidVerificationCode
  103. // }
  104. //}
  105. var u SysUser
  106. var role SysRole
  107. var dept SysDept
  108. var e error
  109. if loginVals.Type == 1 {
  110. u, role, dept, e = loginVals.GetUser(ormDB)
  111. if e != nil {
  112. msg = e.Error()
  113. status = "1"
  114. log.Warnf("%s login failed!", username)
  115. return nil, jwt.ErrFailedAuthentication
  116. }
  117. }
  118. if loginVals.Type == 2 {
  119. u, role, dept, e = loginVals.GetUserByCode(ormDB)
  120. if e != nil {
  121. msg = e.Error()
  122. status = "1"
  123. log.Warnf("%s login failed!", username)
  124. return nil, jwt.ErrFailedSmsVerifyCode
  125. }
  126. }
  127. if loginVals.Type == 3 {
  128. u, role, dept, e = loginVals.GetUserByWX(ormDB)
  129. if e != nil {
  130. msg = e.Error()
  131. status = "1"
  132. log.Warnf("%s login failed!", username)
  133. return nil, jwt.ErrFailedSmsVerifyCode
  134. }
  135. }
  136. if loginVals.Type == 0 {
  137. return nil, jwt.ErrFailedAuthentication
  138. }
  139. username = loginVals.Username
  140. var single bool
  141. //single, err = GetSingleLogin(c)
  142. //if err != nil {
  143. // return nil, err
  144. //}
  145. // 加载用户岗位
  146. var post SysPost
  147. if u.PostId > 0 {
  148. ormDB.Table("sys_post").Where("id = ? AND status = '2'", u.PostId).First(&post)
  149. }
  150. return map[string]interface{}{"user": u, "role": role, "dept": dept, "post": post, "single": single, "mobile": loginVals.Mobile}, nil
  151. }
  152. // LoginLogToDB Write log to database
  153. func LoginLogToDB(c *gin.Context, status string, msg string, username string) {
  154. if !config.LoggerConfig.EnabledDB {
  155. return
  156. }
  157. log := api.GetRequestLogger(c)
  158. l := make(map[string]interface{})
  159. ua := user_agent.New(c.Request.UserAgent())
  160. l["ipaddr"] = common.GetClientIP(c)
  161. l["loginTime"] = pkg.GetCurrentTime()
  162. l["status"] = status
  163. l["remark"] = c.Request.UserAgent()
  164. browserName, browserVersion := ua.Browser()
  165. l["browser"] = browserName + " " + browserVersion
  166. l["os"] = ua.OS()
  167. l["platform"] = ua.Platform()
  168. l["username"] = username
  169. l["msg"] = msg
  170. q := sdk.Runtime.GetMemoryQueue(c.Request.Host)
  171. message, err := sdk.Runtime.GetStreamMessage("", global.LoginLog, l)
  172. if err != nil {
  173. log.Errorf("GetStreamMessage error, %s", err.Error())
  174. //日志报错错误,不中断请求
  175. } else {
  176. err = q.Append(message)
  177. if err != nil {
  178. log.Errorf("Append message error, %s", err.Error())
  179. }
  180. }
  181. }
  182. // LogOut 退出登录
  183. // @Summary 退出登录
  184. // @Description 退出登录
  185. // @Description LoginHandler can be used by clients to get a jwt token.
  186. // @Description Reply will be of the form {"token": "TOKEN"}.
  187. // @Tags 登录
  188. // @Accept application/json
  189. // @Product application/json
  190. // @Success 200 {string} string "{"code": 200, "msg": "成功退出系统"}"
  191. // @Router /logout [post]
  192. // @Security Bearer
  193. func LogOut(c *gin.Context) {
  194. LoginLogToDB(c, "2", "退出成功", user.GetUserName(c))
  195. c.JSON(http.StatusOK, gin.H{
  196. "code": 200,
  197. "msg": "退出成功",
  198. })
  199. }
  200. func Authorizator(data interface{}, c *gin.Context) bool {
  201. if v, ok := data.(map[string]interface{}); ok {
  202. u, _ := v["user"].(model.SysUser)
  203. r, _ := v["role"].(model.SysRole)
  204. d, _ := v["dept"].(model.SysDept)
  205. single, _ := v["single"].(bool)
  206. c.Set("uuid", u.Uuid)
  207. c.Set("identity", u.Id)
  208. c.Set("userName", u.Username)
  209. c.Set("roleName", r.Name)
  210. c.Set("roleKey", r.RoleKey)
  211. c.Set("userId", u.Id)
  212. c.Set("roleId", r.Id)
  213. c.Set("single", single)
  214. c.Set("dataScope", r.DataScope)
  215. c.Set("deptId", u.DeptId)
  216. c.Set("deptName", d.Name)
  217. c.Set("postId", u.PostId)
  218. c.Set("postCode", "")
  219. return true
  220. }
  221. return false
  222. }
  223. func Unauthorized(c *gin.Context, code int, message string) {
  224. c.JSON(http.StatusOK, gin.H{
  225. "code": code,
  226. "msg": message,
  227. })
  228. }
  229. // 保存token到redis
  230. func SaveNewestToken(c *gin.Context, userId int64, token string, expire int64) error {
  231. key := fmt.Sprintf("%s:%d", "bzd.oauth.token", userId)
  232. return sdk.Runtime.GetCacheAdapter().Set(key, token, int(expire))
  233. }
  234. // redis从redis获取token
  235. func GetNewestToken(c *gin.Context, userId int64) (string, error) {
  236. key := fmt.Sprintf("%s:%d", "bzd.oauth.token", userId)
  237. return sdk.Runtime.GetCacheAdapter().Get(key)
  238. }
  239. func GetSingleLogin(c *gin.Context) (bool, error) {
  240. log := api.GetRequestLogger(c)
  241. ormDB, err := pkg.GetOrm(c)
  242. if err != nil {
  243. log.Errorf("get db error, %s", err.Error())
  244. response.Error(c, 500, err, "数据库连接获取失败")
  245. return false, err
  246. }
  247. //result := map[string]interface{}{}
  248. var result string
  249. err = ormDB.Table("sys_config").Select("config_value").Where("config_key = ? ", "sys_single_login").Scan(&result).Error
  250. if err != nil {
  251. if errors.Is(err, gorm.ErrRecordNotFound) || err.(*mysql.MySQLError).Number == 1146 {
  252. // 默认为非单一登录
  253. return false, nil
  254. }
  255. log.Errorf("get sys_config error, %s", err.Error())
  256. return false, err
  257. }
  258. if result == "是" {
  259. return true, nil
  260. }
  261. return false, nil
  262. }
  263. func SetEnterDeptId(c *gin.Context, newToken string, userId int64) error {
  264. oldToken := ""
  265. list := strings.Split(c.Request.Header.Get("Authorization"), ".")
  266. if len(list) > 0 {
  267. oldToken = list[len(list)-1]
  268. } else {
  269. return errors.New("token is null")
  270. }
  271. list2 := strings.Split(newToken, ".")
  272. newToken2 := list2[len(list2)-1]
  273. deptIdStr, err := sdk.Runtime.GetCacheAdapter().Get(fmt.Sprintf("enter-dept-%s-%d", oldToken, userId))
  274. if err == nil {
  275. sdk.Runtime.GetCacheAdapter().Set(fmt.Sprintf("enter-dept-%s-%d", newToken2, userId), deptIdStr, int(config.JwtConfig.Timeout)+7200)
  276. sdk.Runtime.GetCacheAdapter().Del(fmt.Sprintf("enter-dept-%s-%d", oldToken, userId))
  277. }
  278. deptName, err := sdk.Runtime.GetCacheAdapter().Get(fmt.Sprintf("enter-dept-name-%s-%d", oldToken, userId))
  279. if err == nil {
  280. sdk.Runtime.GetCacheAdapter().Set(fmt.Sprintf("enter-dept-name-%s-%d", newToken2, userId), deptName, int(config.JwtConfig.Timeout)+7200)
  281. sdk.Runtime.GetCacheAdapter().Del(fmt.Sprintf("enter-dept-name-%s-%d", oldToken, userId))
  282. }
  283. if err == redis.Nil {
  284. return nil
  285. }
  286. return err
  287. }