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

148 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}