loginbyweixinlogic.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package logic
  2. import (
  3. "context"
  4. "crypto/sha1"
  5. "encoding/base64"
  6. "encoding/hex"
  7. "encoding/json"
  8. "errors"
  9. "fmt"
  10. "time"
  11. "git.i2edu.net/i2/go-zero/core/logx"
  12. "git.i2edu.net/i2/go-zero/core/stores/sqlc"
  13. "git.i2edu.net/i2/i2-bill-api/internal/svc"
  14. "git.i2edu.net/i2/i2-bill-api/internal/types"
  15. "git.i2edu.net/i2/i2-bill-api/internal/utils"
  16. "git.i2edu.net/i2/i2-bill-api/model"
  17. "git.i2edu.net/i2/i2-bill-erp/transformclient"
  18. "github.com/dgrijalva/jwt-go"
  19. )
  20. type LoginByWeixinLogic struct {
  21. logx.Logger
  22. ctx context.Context
  23. svcCtx *svc.ServiceContext
  24. }
  25. func NewLoginByWeixinLogic(ctx context.Context, svcCtx *svc.ServiceContext) LoginByWeixinLogic {
  26. return LoginByWeixinLogic{
  27. Logger: logx.WithContext(ctx),
  28. ctx: ctx,
  29. svcCtx: svcCtx,
  30. }
  31. }
  32. func (l *LoginByWeixinLogic) LoginByWeixin(req types.AuthLoginBody) (*types.AuthResponse, error) {
  33. alb := req
  34. userInfo, err := l.Login(alb.Code, alb.UserInfo)
  35. if err != nil {
  36. return nil, err
  37. }
  38. //
  39. resp, err := l.svcCtx.Transformer.GetUser(l.ctx, &transformclient.Request{
  40. Id: "0909",
  41. })
  42. if err != nil {
  43. return nil, err
  44. }
  45. fmt.Println(resp.Roles)
  46. user, err := l.svcCtx.UserModel.FindOneByWeiXinOpenId(userInfo.OpenID)
  47. if err == sqlc.ErrNotFound {
  48. newuser := model.User{Username: utils.GetUUID(), Password: "", RegisterTime: utils.GetTimestamp(),
  49. RegisterIp: "", Mobile: "", WeixinOpenid: userInfo.OpenID, Avatar: userInfo.AvatarUrl, Gender: userInfo.Gender,
  50. Nickname: userInfo.NickName}
  51. l.svcCtx.UserModel.Insert(newuser)
  52. user, _ = l.svcCtx.UserModel.FindOneByWeiXinOpenId(userInfo.OpenID)
  53. }
  54. rtnInfo := types.AuthResponse{}
  55. rtnInfo.UserInfo.ID = user.Id
  56. rtnInfo.UserInfo.UserName = user.Username
  57. rtnInfo.UserInfo.NickName = user.Nickname
  58. rtnInfo.UserInfo.Gender = user.Gender
  59. rtnInfo.UserInfo.Avatar = user.Avatar
  60. rtnInfo.UserInfo.Birthday = user.Birthday
  61. user.LastLoginIp = ""
  62. user.LastLoginTime = utils.GetTimestamp()
  63. if err := l.svcCtx.UserModel.Update(*user); err == nil {
  64. return nil, err
  65. }
  66. var accessExpire = l.svcCtx.Config.JwtAuth.AccessExpire
  67. now := time.Now().Unix()
  68. payloads := map[string]interface{}{
  69. "user_id": user.Id,
  70. }
  71. accessToken, err := l.CreateJWT(now, l.svcCtx.Config.JwtAuth.AccessSecret, payloads, accessExpire)
  72. if err != nil {
  73. return nil, err
  74. }
  75. rtnInfo.Token = accessToken
  76. return &rtnInfo, nil
  77. }
  78. func (l *LoginByWeixinLogic) CreateJWT(iat int64, secretKey string, payloads map[string]interface{}, seconds int64) (string, error) {
  79. claims := make(jwt.MapClaims)
  80. claims["exp"] = iat + seconds
  81. claims["iat"] = iat
  82. for k, v := range payloads {
  83. claims[k] = v
  84. }
  85. token := jwt.New(jwt.SigningMethodHS256)
  86. token.Claims = claims
  87. return token.SignedString([]byte(secretKey))
  88. }
  89. func (l *LoginByWeixinLogic) Login(code string, fullUserInfo types.ResUserInfo) (*types.WXUserInfo, error) {
  90. secret := l.svcCtx.Config.Weixin.Secret
  91. appid := l.svcCtx.Config.Weixin.Appid
  92. req := utils.Get("https://api.weixin.qq.com/sns/jscode2session")
  93. req.Param("grant_type", "authorization_code")
  94. req.Param("js_code", code)
  95. req.Param("secret", secret)
  96. req.Param("appid", appid)
  97. var res types.WXLoginResponse
  98. req.ToJSON(&res)
  99. s := sha1.New()
  100. s.Write([]byte(fullUserInfo.RawData + res.SessionKey))
  101. sha1 := s.Sum(nil)
  102. sha1hash := hex.EncodeToString(sha1)
  103. if fullUserInfo.Signature != sha1hash {
  104. return nil, errors.New("signature err")
  105. }
  106. userinfo, err := l.DecryptUserInfoData(res.SessionKey, fullUserInfo.EncryptedData, fullUserInfo.IV)
  107. return userinfo, err
  108. }
  109. func (l *LoginByWeixinLogic) DecryptUserInfoData(sessionKey string, encryptedData string, iv string) (*types.WXUserInfo, error) {
  110. sk, _ := base64.StdEncoding.DecodeString(sessionKey)
  111. ed, _ := base64.StdEncoding.DecodeString(encryptedData)
  112. i, _ := base64.StdEncoding.DecodeString(iv)
  113. decryptedData, err := utils.AesCBCDecrypt(ed, sk, i)
  114. if err != nil {
  115. return nil, err
  116. }
  117. var wxuserinfo types.WXUserInfo
  118. err = json.Unmarshal(decryptedData, &wxuserinfo)
  119. if err != nil {
  120. return nil, err
  121. }
  122. return &wxuserinfo, nil
  123. }