wx-server/internal/server/wx/login.go

148 lines
3.9 KiB
Go
Raw Normal View History

2024-06-04 21:22:50 +08:00
package wx
import (
"encoding/json"
"fmt"
"io"
"mini_server/internal/config"
"mini_server/internal/dao"
"mini_server/internal/middleware/jwt"
"mini_server/internal/server/help"
"mini_server/internal/server/httpreply"
"mini_server/internal/server/user"
"net/http"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
type LoginRequest struct {
Code string `json:"code" binding:"min=1"` // 临时会话登录code
}
type LoginReply struct {
Token string `json:"token"` // 返回登录成功的jwt token
UserInfo *user.UserInfo `json:"user_info"`
}
// 微信服务器,返回的数据结构
type WxHttpReply struct {
Errcode int32 `json:"errcode"` // 错误码
Errmsg string `json:"errmsg"` // 错误信息
OpenId string `json:"openid"` // 用户唯一标识
// Unionid string `json:"unionid"` // 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见微信 UnionID
SessionKey string `json:"session_key"` // 会话密钥
}
func WxLogin(c *gin.Context) {
reply := httpreply.NewDefaultReplyData()
defer httpreply.Reply(c, reply)
//解析请求参数
var request LoginRequest
if err := c.ShouldBindJSON(&request); err != nil {
reply.Status = http.StatusBadRequest
reply.Message = fmt.Sprintf("invalid json data, err:%v", err)
return
}
logrus.Tracef("微信登录,请求参数:%v", request)
// 从微信查询openId
openId, err := get_wx_login_open_id(request.Code)
if err != nil {
logrus.Errorf("请求微信获取OpenId失败err:%v", err)
reply.Status = http.StatusServiceUnavailable
reply.Message = "第三方服务错误"
return
}
// 首先查询,是否存在
data, err := dao.User_WX_Query(openId)
if err != nil {
logrus.Errorf("微信登录,数据库查询失败,err%v", err)
reply.Status = http.StatusInternalServerError
reply.Message = "用户查询失败"
return
}
if data == nil { // 用户不存在,则需要添加创建
default_wx_username, err := get_default_wx_username()
if err != nil {
logrus.Errorf("生成微信默认用户名失败,err:%v", err)
reply.Status = http.StatusInternalServerError
reply.Message = "生成微信默认用户名失败"
return
}
data = &dao.User{
AvatarId: "",
OpenId: openId,
Username: default_wx_username, // 默认名称
Persona: "{}",
Tags: "{}",
}
if _, err = dao.User_WX_Insert(data); err != nil {
logrus.Errorf("微信登录,数据库用户添加失败,err%v", err)
reply.Status = http.StatusInternalServerError
reply.Message = "用户添加失败"
return
}
}
// 生成token
token, err := jwt.CreateToken(data)
if err != nil {
logrus.Errorf("微信登录生成token失败err:%v", err)
reply.Status = http.StatusInternalServerError
reply.Message = "token生成失败"
return
}
// 返回用户信息
var info user.UserInfo
user.Copy_User_Info(data, &info)
loginReply := LoginReply{
Token: token,
UserInfo: &info,
}
reply.Data = &loginReply
logrus.Tracef("微信登录成功,应答:%v", reply)
}
func get_wx_login_open_id(code string) (string, error) {
//接口请求url拼接
url := config.WeiXin.AppUrl(code)
// 转发请求到微信接口
resp, err := http.Get(url)
if err != nil {
return "", fmt.Errorf("请求微信登录接口失败err:%v", err)
}
defer resp.Body.Close()
// 读取数据
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("读取微信登录应答数据失败err:%v", err)
}
// 解码数据并赋值给返回的respData
respData := new(WxHttpReply)
json.Unmarshal(body, &respData)
openId := respData.OpenId
// 检测openid是否为空
if openId == "" {
return "", fmt.Errorf("读取微信登录应答数据openId为空")
}
return openId, nil
}
// 注册时返回随机名称
func get_default_wx_username() (string, error) {
id := help.GetUniqueIdEachSecond()
return "微信用户" + id, nil
}