package api import ( "errors" "fmt" "github.com/golang-jwt/jwt/v4" "github.com/jakehl/goid" "github.com/kataras/iris/v12" "github.com/sirupsen/logrus" "main/database" "main/jwtSet" "main/model" "main/service/admin" "main/utils" "math/rand" "strconv" "strings" "time" ) // 返回加密后用户信息 func userinfo(ctx iris.Context) { user := utils.GetLoginUser(ctx) if utils.DataIsNil(user) { return } if user.Email != "" { user.Email = fmt.Sprintf("%s****%s", user.Email[0:2], user.Email[len(user.Email)-7:]) } if user.Mobile != "" { user.Mobile = fmt.Sprintf("%s****%s", user.Mobile[0:2], user.Mobile[len(user.Mobile)-4:]) } err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", user)) if utils.ErrHandle(ctx, err) { return } } // 更新用户信息 func updateUserinfo(ctx iris.Context) { username := utils.GetLoginUser(ctx) if utils.DataIsNil(username) { return } var params model.Userinfo err := ctx.ReadJSON(¶ms) if utils.ErrHandle(ctx, err) { return } db := database.GetInstance().GetMysqlDb() if strings.Contains(params.Email, "*") { params.Email = "" } if strings.Contains(params.Mobile, "*") { params.Mobile = "" } if err1 := db.Model(&model.Userinfo{}).Where("username = ?", username.Username).Updates(params).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } for i, u := range utils.UserList { if u.Username == username.Username { utils.UserList[i] = params } } utils.UpdateUserInfo() err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success")) if utils.ErrHandle(ctx, err) { return } } // 用户登录 func login(ctx iris.Context) (string, error) { username := ctx.URLParam("username") password := ctx.URLParam("password") confirmCode := ctx.URLParam("confirmCode") auto := ctx.URLParam("auto") var res result db := database.GetInstance().GetMysqlDb() if err := db. Model(&model.User{}). Select("users.password, users.confirm_code, users.updated_at, day_keys.key, day_keys.aes_key"). Joins("left join day_keys on day_keys.user = users.username and day_keys.date = users.date"). Where("users.username = ?", username). Order("users.date desc"). Scan(&res).Error; err != nil { logrus.Errorln("sql执行失败:", err) } if utils.DataIsNil(res) { return "", errors.New("用户不存在") } rsaDePass, err := utils.RsaDecrypt(password, res.Key) if err != nil { return "", err } if confirmCode == "" { aesDePass, err := utils.DecryptByAes(res.Password, []byte(res.AesKey)) if err != nil { return "", err } //fmt.Println(string(aesDePass), rsaDePass) if string(aesDePass) != rsaDePass { return "", errors.New("用户信息错误") } } else if res.ConfirmCode != confirmCode { return "", errors.New("验证码错误") } else if res.ConfirmCode != "" && time.Now().After(res.UpdatedAt.Add(time.Minute*5)) { return "", errors.New("验证码已过期") } priKeys, _ := utils.GetPrivateKeys(username, time.Now().Format("2006-01-02")) newPwd, _ := utils.EncryptByAes([]byte(rsaDePass), []byte(priKeys.AesKey)) if err1 := db. Model(&model.User{}). Where("username = ?", username). Updates(map[string]interface{}{ "password": newPwd, "date": time.Now().Format("2006-01-02"), "confirm_code": "", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } rand1 := rand.New(rand.NewSource(time.Now().UnixNano())) token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "username": username, "iat": time.Now().Unix(), "jti": strconv.Itoa(rand1.Int()), "exp": time.Now().Add(2 * time.Hour).Unix(), }) jwtKey := jwtSet.GetJwtKeys().Key tokenString, err := token.SignedString([]byte(jwtKey)) if err != nil { return "", err } ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) ctx.SetCookieKV("loginTime", strconv.FormatInt(time.Now().UnixMilli(), 10), iris.CookieHTTPOnly(false)) if err1 := db.Create(&model.UserAction{ Username: username, Action: "用户登录", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if err1 := db.Create(&model.JwtKeys{ Username: username, Date: time.Now().Format("2006-01-02"), Key: jwtKey, Token: tokenString, }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if auto == "true" { deviceId := goid.NewV4UUID() location := admin.GetIpLocation(utils.GetRequestIp(ctx)) ctx.SetCookieKV("deviceId", deviceId.String(), iris.CookieHTTPOnly(false)) if err1 := db.Create(&model.UserAutoLogin{ Username: username, DeviceId: deviceId.String(), Location: location, }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } } return tokenString, nil } // 用户注册 func register(ctx iris.Context) (string, error) { username := ctx.URLParam("username") password := ctx.URLParam("password") priKeys, err := utils.GetPrivateKeys(username, time.Now().Format("2006-01-02")) if err != nil { return "", err } dePass, err := utils.RsaDecrypt(password, priKeys.Key) if err != nil { return "", err } enPass, err := utils.EncryptByAes([]byte(dePass), []byte(priKeys.AesKey)) if err != nil { return "", err } db := database.GetInstance().GetMysqlDb() var user []model.User if err1 := db.Where("username = ?", username).Find(&user).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if len(user) > 0 { err = errors.New("user exists") return "", err } if err1 := db.Create(&model.User{ Username: username, Password: enPass, Date: time.Now().Format("2006-01-02"), }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if len(utils.UserList) == 0 { if err1 := db.Create(&model.Userinfo{ Username: username, Type: "admin", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } } else { if err1 := db.Create(&model.Userinfo{ Username: username, Type: "user", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } } utils.UpdateUserInfo() rand1 := rand.New(rand.NewSource(time.Now().UnixNano())) token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "username": username, "iat": time.Now().Unix(), "jti": strconv.Itoa(rand1.Int()), "exp": time.Now().Add(2 * time.Hour).Unix(), }) jwtKey := jwtSet.GetJwtKeys().Key tokenString, err := token.SignedString([]byte(jwtKey)) if err != nil { return "", err } ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) ctx.SetCookieKV("loginTime", strconv.FormatInt(time.Now().UnixMilli(), 10), iris.CookieHTTPOnly(false)) if err1 := db.Create(&model.UserAction{ Username: username, Action: "用户注册并登录", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if err1 := db.Create(&model.JwtKeys{ Username: username, Date: time.Now().Format("2006-01-02"), Key: jwtKey, Token: tokenString, }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } return tokenString, nil } // 退出登录 func logout(ctx iris.Context) { db := database.GetInstance().GetMysqlDb() username := utils.GetLoginUser(ctx) auth := ctx.Values().Get("jwt") deviceId := ctx.GetCookie("deviceId") if auth == nil { ctx.StatusCode(iris.StatusUnauthorized) ctx.SetErr(errors.New("未登录")) return } if err := db.Where("token = ?", auth.(*jwt.Token).Raw).Delete(&model.JwtKeys{}).Error; err != nil { logrus.Errorln("sql执行失败:", err) } ctx.RemoveCookie("is_login") ctx.RemoveCookie("token") if deviceId != "" { ctx.RemoveCookie("deviceId") if err := db.Where("device_id = ? and username = ?", deviceId, username).Delete(&model.UserAutoLogin{}).Error; err != nil { logrus.Errorln("sql执行失败:", err) } } if err := db.Create(&model.UserAction{ Username: username.Username, Action: "用户注销登录", }).Error; err != nil { logrus.Errorln("sql执行失败:", err) } err := ctx.JSON(utils.FormatRes(iris.StatusOK, "", "success")) if utils.ErrHandle(ctx, err) { return } } // 重置密码 func resetPwd(ctx iris.Context) { username := ctx.URLParam("username") //var user model.Userinfo db := database.GetInstance().GetMysqlDb() user := utils.GetUserInfo(username) if utils.DataIsNil(user) { ctx.StatusCode(iris.StatusInternalServerError) ctx.SetErr(errors.New("用户不存在")) return } confirmCode := utils.NewKey(8) if err := db.Model(&model.User{}).Where("username = ?", username).Updates(model.User{ConfirmCode: confirmCode}).Error; err != nil { logrus.Errorln("sql执行失败:", err) } err := utils.SendEmail([]string{user.Email}, "密码重置", fmt.Sprintf("验证码为:%s\n您正在进行密码重置,验证码5分钟内有效,如非本人操作,请忽略本邮件", confirmCode)) if utils.ErrHandle(ctx, err) { return } if err1 := db.Create(&model.UserAction{ Username: username, Action: "获取重置密码验证码", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", fmt.Sprintf("%s****%s", user.Email[0:2], user.Email[7:]))) if utils.ErrHandle(ctx, err) { return } } func autoLogin(ctx iris.Context) { var user []model.UserAutoLogin location := admin.GetIpLocation(utils.GetRequestIp(ctx)) deviceId := ctx.GetCookie("deviceId") if deviceId == "" || location == "" { err := ctx.JSON(utils.FormatRes(iris.StatusOK, "自动登录未设置", false)) if utils.ErrHandle(ctx, err) { return } return } db := database.GetInstance().GetMysqlDb() if err := db.Where("device_id = ? and location = ?", deviceId, location).Find(&user).Error; err != nil { logrus.Errorln("sql执行失败:", err) } if len(user) == 0 { err := ctx.JSON(utils.FormatRes(iris.StatusOK, "自动登录未设置", false)) if utils.ErrHandle(ctx, err) { return } return } rand1 := rand.New(rand.NewSource(time.Now().UnixNano())) token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "username": user[0].Username, "iat": time.Now().Unix(), "jti": strconv.Itoa(rand1.Int()), "exp": time.Now().Add(2 * time.Hour).Unix(), }) jwtKey := jwtSet.GetJwtKeys().Key tokenString, err := token.SignedString([]byte(jwtKey)) if utils.ErrHandle(ctx, err) { return } ctx.SetCookieKV("is_login", "1", iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) ctx.SetCookieKV("token", tokenString, iris.CookieHTTPOnly(false), iris.CookieExpires(2*time.Hour)) if err1 := db.Create(&model.UserAction{ Username: user[0].Username, Action: "用户自动登录", }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } if err1 := db.Create(&model.JwtKeys{ Username: user[0].Username, Date: time.Now().Format("2006-01-02"), Key: jwtKey, Token: tokenString, }).Error; err1 != nil { logrus.Errorln("sql执行失败:", err1) } err = ctx.JSON(utils.FormatRes(iris.StatusOK, "", tokenString)) if utils.ErrHandle(ctx, err) { return } }