loginbyweixinlogic.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package auth
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "time"
  7. "git.i2edu.net/i2/go-zero/core/logx"
  8. "git.i2edu.net/i2/go-zero/core/stores/sqlc"
  9. "git.i2edu.net/i2/go-zero/core/stores/sqlx"
  10. "git.i2edu.net/i2/i2-bill-api/internal/svc"
  11. "git.i2edu.net/i2/i2-bill-api/internal/types"
  12. "git.i2edu.net/i2/i2-bill-api/internal/utils"
  13. "git.i2edu.net/i2/i2-bill-api/model"
  14. "github.com/dgrijalva/jwt-go"
  15. )
  16. type LoginByWeixinLogic struct {
  17. logx.Logger
  18. ctx context.Context
  19. svcCtx *svc.ServiceContext
  20. }
  21. func NewLoginByWeixinLogic(ctx context.Context, svcCtx *svc.ServiceContext) LoginByWeixinLogic {
  22. return LoginByWeixinLogic{
  23. Logger: logx.WithContext(ctx),
  24. ctx: ctx,
  25. svcCtx: svcCtx,
  26. }
  27. }
  28. func (l *LoginByWeixinLogic) LoginByWeixin(req types.LoginByWeixinRequest) (*types.LoginByWeixinResponse, error) {
  29. alb, rtnInfo := req, types.LoginByWeixinResponse{}
  30. userInfo, err := l.Login(alb.Code)
  31. if err != nil {
  32. logx.Error(err)
  33. return nil, err
  34. }
  35. err = l.svcCtx.SqlConn.Transact(func(session sqlx.Session) error {
  36. var user model.User
  37. err := session.QueryRowPartial(&user, fmt.Sprintf("select %s from i2bill_user where `weixin_openid` = ? limit 1", model.UserRows), userInfo.OpenID)
  38. if err == sqlc.ErrNotFound {
  39. user.Username = utils.GetUUID()
  40. user.Password = ""
  41. user.RegisterTime = utils.GetTimestamp()
  42. user.RegisterIp = ""
  43. user.Mobile = ""
  44. user.WeixinOpenid = userInfo.OpenID
  45. user.Avatar = userInfo.AvatarUrl
  46. user.Gender = userInfo.Gender
  47. user.Nickname = userInfo.NickName
  48. _, err = session.Exec(`insert into i2bill_user (%s) values (
  49. mobile, avatar, weixin_openid, password, birthday, register_time, last_login_time, nickname,
  50. erp_id, username, gender, user_level_id, register_ip, last_login_ip
  51. )`,
  52. user.Mobile, user.Avatar, user.WeixinOpenid, user.Password, user.Birthday, user.RegisterTime, user.LastLoginTime, user.Nickname, user.ErpId, user.Username, user.Gender, user.UserLevelId, user.RegisterIp, user.LastLoginIp)
  53. if err != nil {
  54. logx.Error(err)
  55. return err
  56. }
  57. err = session.QueryRowPartial(&user, fmt.Sprintf("select %s from i2bill_user where `weixin_openid` = ? limit 1", model.UserRows), userInfo.OpenID)
  58. if err != nil {
  59. logx.Error(err)
  60. return err
  61. }
  62. }
  63. rtnInfo.UserInfo.ID = user.Id
  64. rtnInfo.UserInfo.UserName = user.Username
  65. rtnInfo.UserInfo.NickName = user.Nickname
  66. rtnInfo.UserInfo.Mobile = user.Mobile
  67. rtnInfo.UserInfo.Gender = user.Gender
  68. rtnInfo.UserInfo.Avatar = user.Avatar
  69. rtnInfo.UserInfo.Birthday = user.Birthday
  70. user.LastLoginIp = ""
  71. user.LastLoginTime = utils.GetTimestamp()
  72. _, err = session.Exec(`update i2bill_user set
  73. mobile = ?, avatar = ?, weixin_openid = ?, password = ?, birthday = ?, register_time = ?, last_login_time = ?,
  74. nickname = ?, erp_id = ?, username = ?, gender = ?, user_level_id = ?, register_ip = ?, last_login_ip = ? where id = ?`, user.Mobile, user.Avatar, user.WeixinOpenid, user.Password, user.Birthday, user.RegisterTime, user.LastLoginTime, user.Nickname, user.ErpId, user.Username, user.Gender, user.UserLevelId, user.RegisterIp, user.LastLoginIp, user.Id)
  75. if err != nil {
  76. logx.Error(err)
  77. return err
  78. }
  79. return nil
  80. })
  81. if err != nil {
  82. return nil, err
  83. }
  84. var accessExpire = l.svcCtx.Config.JwtAuth.AccessExpire
  85. now := time.Now().Unix()
  86. payloads := map[string]interface{}{
  87. "userId": rtnInfo.UserInfo.ID,
  88. "sessionKey": userInfo.SessionKey,
  89. }
  90. accessToken, err := l.CreateJWT(now, l.svcCtx.Config.JwtAuth.AccessSecret, payloads, accessExpire)
  91. if err != nil {
  92. logx.Error(err)
  93. return nil, err
  94. }
  95. rtnInfo.Token = accessToken
  96. return &rtnInfo, nil
  97. }
  98. func (l *LoginByWeixinLogic) CreateJWT(iat int64, secretKey string, payloads map[string]interface{}, seconds int64) (string, error) {
  99. claims := make(jwt.MapClaims)
  100. claims["exp"] = iat + seconds
  101. claims["iat"] = iat
  102. for k, v := range payloads {
  103. claims[k] = v
  104. }
  105. token := jwt.New(jwt.SigningMethodHS256)
  106. token.Claims = claims
  107. return token.SignedString([]byte(secretKey))
  108. }
  109. func (l *LoginByWeixinLogic) Login(code string) (*types.WXUserInfo, error) {
  110. secret := l.svcCtx.Config.Weixin.Secret
  111. appid := l.svcCtx.Config.Weixin.Appid
  112. req := utils.Get("https://api.weixin.qq.com/sns/jscode2session")
  113. req.Param("grant_type", "authorization_code")
  114. req.Param("js_code", code)
  115. req.Param("secret", secret)
  116. req.Param("appid", appid)
  117. var res types.WXLoginResponse
  118. req.ToJSON(&res)
  119. if res.ErrCode != 0 {
  120. return nil, errors.New(res.ErrMsg)
  121. }
  122. userinfo, err := l.DecryptUserInfoData(res.SessionKey)
  123. userinfo.OpenID = res.OpenID
  124. userinfo.SessionKey = res.SessionKey
  125. return userinfo, err
  126. }
  127. func (l *LoginByWeixinLogic) DecryptUserInfoData(sessionKey string) (*types.WXUserInfo, error) {
  128. var wxuserinfo types.WXUserInfo
  129. return &wxuserinfo, nil
  130. }