附近小店
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

mw_auth_jwt.go 2.9 KiB

před 2 měsíci
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package mw
  2. import (
  3. "applet/app/db"
  4. "applet/app/db/model"
  5. "applet/app/e"
  6. "applet/app/lib/auth"
  7. "applet/app/md"
  8. "applet/app/svc"
  9. "applet/app/utils"
  10. "applet/app/utils/cache"
  11. "applet/app/utils/logx"
  12. "errors"
  13. "fmt"
  14. "strings"
  15. "github.com/gin-gonic/gin"
  16. )
  17. // AuthJWT is jwt middleware
  18. func AuthJWT(c *gin.Context) {
  19. authHeader := c.Request.Header.Get("Authorization")
  20. if authHeader == "" {
  21. e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 不能为空"))
  22. return
  23. }
  24. // 按空格分割
  25. parts := strings.SplitN(authHeader, " ", 2)
  26. if !(len(parts) == 2 && parts[0] == "Bearer") {
  27. e.OutErr(c, e.ERR_TOKEN_FORMAT, errors.New("token 格式不对"))
  28. return
  29. }
  30. // parts[1]是token
  31. mc, err := utils.ParseToken(parts[1])
  32. if err != nil {
  33. e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 过期或无效"))
  34. return
  35. }
  36. // 获取user
  37. u, err := db.UserFindByID(db.DBs[c.GetString("mid")], mc.UID)
  38. if err != nil {
  39. e.OutErr(c, e.ERR_DB_ORM, err)
  40. return
  41. }
  42. if u == nil {
  43. e.OutErr(c, e.ERR_UNAUTHORIZED, errors.New("token 过期或无效"))
  44. return
  45. }
  46. // 检验账号是否未激活或被冻结
  47. switch u.State {
  48. case 0:
  49. e.OutErr(c, e.ERR_USER_NO_ACTIVE)
  50. return
  51. case 2:
  52. if c.GetString("mid") == "31585332" {
  53. utils.FilePutContents("ERR_USER_IS_BAN", utils.SerializeStr(map[string]interface{}{
  54. "token": parts[1],
  55. "mc": mc,
  56. "user": u,
  57. }))
  58. }
  59. e.OutErr(c, e.ERR_USER_IS_BAN)
  60. return
  61. }
  62. // 校验是否和缓存的token一致,只能有一个token 是真实有效
  63. key := fmt.Sprintf("%s:token:%s", c.GetString("mid"), u.Username)
  64. cjwt, err := cache.GetString(key)
  65. fmt.Println("====================token", u.Username, key, cjwt, parts[1])
  66. if err != nil {
  67. fmt.Println("====================token", err)
  68. logx.Warn(err)
  69. NOCACHE(c, parts, mc, u, false)
  70. return
  71. }
  72. if parts[1] != cjwt {
  73. e.OutErr(c, e.ERR_TOKEN_AUTH, errors.New("token expired"))
  74. return
  75. }
  76. NOCACHE(c, parts, mc, u, true)
  77. }
  78. func NOCACHE(c *gin.Context, parts []string, mc *auth.JWTUser, u *model.User, isTrue bool) {
  79. // 获取user profile
  80. up, err := db.UserProfileFindByID(db.DBs[c.GetString("mid")], mc.UID)
  81. if err != nil || up == nil {
  82. e.OutErr(c, e.ERR_DB_ORM, err)
  83. return
  84. }
  85. if parts[1] != up.ArkidToken && isTrue == false || up.ArkidToken == "" {
  86. e.OutErr(c, e.ERR_TOKEN_AUTH, errors.New("token expired"))
  87. return
  88. }
  89. if parts[1] != up.ArkidToken && isTrue {
  90. up.ArkidToken = parts[1]
  91. db.UserProfileUpdate(svc.MasterDb(c), up.Uid, up, "arkid_token")
  92. }
  93. if up.AvatarUrl == "" {
  94. up.AvatarUrl = c.GetString("appUserDefaultAvatar")
  95. }
  96. // 获取user 等级
  97. ul, err := db.UserLevelByID(db.DBs[c.GetString("mid")], u.Level)
  98. if err != nil {
  99. e.OutErr(c, e.ERR_DB_ORM, err)
  100. return
  101. }
  102. user := &md.User{
  103. Info: u,
  104. Profile: up,
  105. Level: ul,
  106. }
  107. // 将当前请求的username信息保存到请求的上下文c上
  108. c.Set("user", user)
  109. c.Next() // 后续的处理函数可以用过c.Get("user")来获取当前请求的用户信息
  110. }