videoplayer/handler/user.go

263 lines
8.8 KiB
Go

package handler
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"github.com/google/uuid"
"time"
"videoplayer/service"
"videoplayer/worker"
)
var signingKey = []byte("aadafcvretmoi9")
func SetUpUserGroup(router *gin.Engine) {
userGroup := router.Group("/user")
userGroup.POST("/register", registerHandler)
userGroup.POST("/login", loginHandler)
userGroup.POST("/uuid", GetScanUUID)
userGroup.POST("/gqr", GetQRStatus)
userGroup.POST("/sqr", SetQRStatus)
userGroup.POST("/confirm", ConfirmQRLogin)
}
type RLReq struct {
User string `json:"username" form:"username"`
Email string `json:"email" form:"email"`
Password string `json:"password" form:"password"`
Age int `json:"age" form:"age"`
Gender string `json:"gender" form:"gender"`
}
type QRReq struct {
UUID string `json:"uuid" form:"uuid"`
Address string `json:"address" form:"address"`
IP string `json:"ip" form:"ip"`
}
func GetScanUUID(c *gin.Context) {
var ReqData QRReq
if err := c.ShouldBind(&ReqData); err != nil {
c.JSON(200, gin.H{"code": 9, "message": err, "data": "2"})
return
}
data := map[string]interface{}{"status": "0", "address": ReqData.Address, "ip": c.ClientIP()}
jsonData, err := json.Marshal(data)
if err != nil {
c.JSON(200, gin.H{"code": 9, "message": err, "data": "2"})
return
}
id := uuid.New()
res := worker.SetRedisWithExpire(id.String(), string(jsonData), time.Minute*30)
if res {
var retrievedData map[string]interface{}
if err2 := json.Unmarshal([]byte(worker.GetRedis(id.String())), &retrievedData); err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
c.JSON(200, gin.H{"code": 0, "message": retrievedData, "data": id.String()})
} else {
c.JSON(200, gin.H{"code": 8, "message": "qr code invalid", "data": "1"})
}
}
func SetQRStatus(c *gin.Context) {
var qrsetReq QRReq
if err := c.ShouldBind(&qrsetReq); err == nil && qrsetReq.UUID != "" {
if worker.IsContainKey(qrsetReq.UUID) == false {
c.JSON(200, gin.H{"code": 18, "message": "uuid not found in server", "data": "0"})
return
}
var retrievedData map[string]interface{}
if err2 := json.Unmarshal([]byte(worker.GetRedis(qrsetReq.UUID)), &retrievedData); err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
retrievedData["status"] = "1"
jsonData, err2 := json.Marshal(retrievedData)
if err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
res := worker.SetRedisWithExpire(qrsetReq.UUID, string(jsonData), time.Minute*30)
if res {
c.JSON(200, gin.H{"code": 0, "message": "success", "data": retrievedData})
} else {
c.JSON(200, gin.H{"code": 8, "message": "qr code invalid", "data": "1"})
}
} else {
c.JSON(200, gin.H{"code": 9, "message": err, "data": "2"})
}
}
// 确认返回token数据
func ConfirmQRLogin(c *gin.Context) {
var qrsetReq QRReq
if err := c.ShouldBind(&qrsetReq); err == nil && qrsetReq.UUID != "" {
//user_id, _ := c.Get("id")
user_name, _ := c.Get("username")
if user_name != "" {
key := "user_" + user_name.(string)
token := worker.GetRedis(key)
if token == "" {
c.JSON(200, gin.H{"code": 20, "message": "Token不存在", "data": "20"})
}
if worker.IsContainKey(qrsetReq.UUID) == false {
c.JSON(200, gin.H{"code": 18, "message": "uuid not found in server", "data": "0"})
return
}
var retrievedData map[string]interface{}
if err2 := json.Unmarshal([]byte(worker.GetRedis(qrsetReq.UUID)), &retrievedData); err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
retrievedData["status"] = token
jsonData, err2 := json.Marshal(retrievedData)
if err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
if worker.SetRedisWithExpire(qrsetReq.UUID, string(jsonData), time.Minute*10) {
c.JSON(200, gin.H{"code": 0, "message": "success", "data": "0"})
} else {
c.JSON(200, gin.H{"code": 8, "message": "设置Token失败", "data": "8"})
}
} else {
c.JSON(200, gin.H{"code": 20, "message": "failed", "data": "20"})
}
} else {
c.JSON(200, gin.H{"code": 9, "message": err, "data": "3"})
}
}
func GetQRStatus(c *gin.Context) {
var qrReq QRReq
if err := c.ShouldBind(&qrReq); err == nil {
var retrievedData map[string]interface{}
if err2 := json.Unmarshal([]byte(worker.GetRedis(qrReq.UUID)), &retrievedData); err2 != nil {
c.JSON(200, gin.H{"code": 9, "message": err2, "data": "2"})
return
}
str := retrievedData["status"].(string)
switch str {
case "":
c.JSON(200, gin.H{"code": 18, "message": "uuid not found", "data": "0"}) //空值
case "0":
c.JSON(200, gin.H{"code": 0, "message": "success", "data": "0"}) //空值
case "1":
c.JSON(200, gin.H{"code": 0, "message": "success", "data": "1"}) //已扫描待确认
default:
// 解析 JWT 令牌
token, err := jwt.Parse(str, func(token *jwt.Token) (interface{}, error) {
return signingKey, nil
})
if err != nil {
c.JSON(200, gin.H{"error": err.Error(), "code": 19, "message": "error"})
return
}
// 返回令牌
data := make(map[string]interface{})
data["id"] = token.Claims.(jwt.MapClaims)["id"]
data["username"] = token.Claims.(jwt.MapClaims)["username"]
data["email"] = token.Claims.(jwt.MapClaims)["email"]
data["token"] = str
c.JSON(200, gin.H{"code": 0, "message": "success", "data": data}) //确认返回token数据
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": 9, "message": "error"})
}
}
func loginHandler(c *gin.Context) {
var req_data RLReq
tokenString := ""
if err := c.ShouldBind(&req_data); err == nil {
if len(req_data.Password) != 32 {
hasher := md5.New()
hasher.Write([]byte(req_data.Password)) // 生成密码的 MD5 散列值
req_data.Password = hex.EncodeToString(hasher.Sum(nil)) // 生成密码的 MD5 散列值
}
user := service.GetUser(req_data.User, req_data.Password, req_data.Password)
if user.ID != 0 {
key := "user_" + user.Name
redis_token := worker.GetRedis(string(key))
if redis_token == "" {
// 生成 JWT 令牌
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": user.Name,
"id": user.ID,
"exp": time.Now().Add(time.Hour * 10).Unix(), // 令牌过期时间, 10小时后过期
})
tokenString, err = token.SignedString(signingKey)
if err != nil {
c.JSON(200, gin.H{"error": err.Error(), "code": 5, "message": "error"})
return
}
worker.SetRedisWithExpire("user_"+user.Name, tokenString, time.Hour*10) // 将用户信息存入
worker.SetRedisWithExpire(tokenString, tokenString, time.Hour*10) // 设置过期时间为10分钟
data := make(map[string]interface{})
data["id"] = user.ID
data["username"] = user.Name
data["email"] = user.Email
worker.SetHash(tokenString, data) // 将用户信息存入
} else {
tokenString = redis_token
}
// 返回令牌
data := make(map[string]interface{})
data["id"] = user.ID
data["username"] = user.Name
data["email"] = user.Email
data["token"] = tokenString
c.JSON(200, gin.H{"code": 0, "message": "success", "data": data})
} else {
//用户名或密码错误
c.JSON(200, gin.H{"error": "用户名或密码错误", "code": 6, "message": "error"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": 9, "message": "error"})
}
}
func registerHandler(c *gin.Context) {
var req_data RLReq
tokenString := ""
if err := c.ShouldBindJSON(&req_data); err == nil {
if len(req_data.Password) != 32 {
hasher := md5.New()
hasher.Write([]byte(req_data.Password)) // 生成密码的 MD5 散列值
req_data.Password = hex.EncodeToString(hasher.Sum(nil)) // 生成密码的 MD5 散列值
}
if service.ContainsUser(req_data.User, req_data.Email) == true {
c.JSON(200, gin.H{"error": "user already exists", "code": 7, "message": "error"})
return
}
id := service.CreateUser(req_data.User, req_data.Password, req_data.Email)
// 生成 JWT 令牌
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": req_data.User,
"id": id,
"exp": time.Now().Add(time.Hour * 10).Unix(), // 令牌过期时间, 1分钟后过期
})
tokenString, err = token.SignedString(signingKey)
if err != nil {
c.JSON(200, gin.H{"error": err.Error(), "code": 5, "message": "error"})
}
} else {
c.JSON(200, gin.H{"error": err.Error(), "code": 9, "message": "error"})
}
fmt.Println(req_data)
res := worker.SetRedisWithExpire(tokenString, tokenString, time.Hour*10) // 设置过期时间为10分钟
if !res {
c.JSON(200, gin.H{"error": "set token error", "code": 8, "message": "error"})
return
}
// 返回令牌
c.JSON(200, gin.H{"token": tokenString, "username": req_data.User, "code": 0, "message": "success"})
}