mirror of
https://github.com/snowykami/neo-blog.git
synced 2025-09-03 15:56:22 +00:00
⚡ implement user registration with email verification, enhance error handling, and update database configuration
This commit is contained in:
@ -20,16 +20,17 @@ type UserLoginResp struct {
|
||||
}
|
||||
|
||||
type UserRegisterReq struct {
|
||||
Username string `json:"username"` // 用户名
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
Password string `json:"password"` // 密码
|
||||
Email string `json:"email"` // 邮箱
|
||||
Username string `json:"username"` // 用户名
|
||||
Nickname string `json:"nickname"` // 昵称
|
||||
Password string `json:"password"` // 密码
|
||||
Email string `json:"email"` // 邮箱
|
||||
VerificationCode string `json:"verification_code"` // 邮箱验证码
|
||||
}
|
||||
|
||||
type UserRegisterResp struct {
|
||||
Token string `json:"token"` // 访问令牌
|
||||
RefreshToken string `json:"refresh_token"` // 刷新令牌
|
||||
User UserDto `json:"user"` // 用户信息
|
||||
Token string `json:"token"` // 访问令牌
|
||||
RefreshToken string `json:"refresh_token"` // 刷新令牌
|
||||
User *UserDto `json:"user"` // 用户信息
|
||||
}
|
||||
|
||||
type VerifyEmailReq struct {
|
||||
|
@ -7,10 +7,10 @@ import (
|
||||
|
||||
type User struct {
|
||||
gorm.Model
|
||||
Username string `gorm:"unique;index"` // 用户名,唯一
|
||||
Username string `gorm:"uniqueIndex"` // 用户名,唯一
|
||||
Nickname string
|
||||
AvatarUrl string
|
||||
Email string `gorm:"unique;index"`
|
||||
Email string `gorm:"uniqueIndex"`
|
||||
Gender string
|
||||
Role string `gorm:"default:'user'"`
|
||||
|
||||
|
@ -35,14 +35,14 @@ type DBConfig struct {
|
||||
// loadDBConfig 从配置文件加载数据库配置
|
||||
func loadDBConfig() DBConfig {
|
||||
return DBConfig{
|
||||
Driver: utils.Env.Get("database.driver", "sqlite"),
|
||||
Path: utils.Env.Get("database.path", "./data/data.db"),
|
||||
Host: utils.Env.Get("database.host", "postgres"),
|
||||
Port: utils.Env.GetenvAsInt("database.port", 5432),
|
||||
User: utils.Env.Get("database.user", "spage"),
|
||||
Password: utils.Env.Get("database.password", "spage"),
|
||||
DBName: utils.Env.Get("database.dbname", "spage"),
|
||||
SSLMode: utils.Env.Get("database.sslmode", "disable"),
|
||||
Driver: utils.Env.Get("DB_DRIVER", "sqlite"),
|
||||
Path: utils.Env.Get("DB_PATH", "./data/data.db"),
|
||||
Host: utils.Env.Get("DB_HOST", "postgres"),
|
||||
Port: utils.Env.GetenvAsInt("DB_PORT", 5432),
|
||||
User: utils.Env.Get("DB_USER", "blog"),
|
||||
Password: utils.Env.Get("DB_PASSWORD", "blog"),
|
||||
DBName: utils.Env.Get("DB_NAME", "blog"),
|
||||
SSLMode: utils.Env.Get("DB_SSLMODE", "disable"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,13 @@ package service
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/snowykami/neo-blog/internal/dto"
|
||||
"github.com/snowykami/neo-blog/internal/model"
|
||||
"github.com/snowykami/neo-blog/internal/repo"
|
||||
"github.com/snowykami/neo-blog/internal/static"
|
||||
"github.com/snowykami/neo-blog/pkg/constant"
|
||||
"github.com/snowykami/neo-blog/pkg/errs"
|
||||
"github.com/snowykami/neo-blog/pkg/utils"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -62,7 +64,57 @@ func (s *userService) UserLogin(req *dto.UserLoginReq) (*dto.UserLoginResp, erro
|
||||
}
|
||||
|
||||
func (s *userService) UserRegister(req *dto.UserRegisterReq) (*dto.UserRegisterResp, error) {
|
||||
return nil, nil
|
||||
// 验证邮箱验证码
|
||||
kv := utils.KV.GetInstance()
|
||||
verificationCode, ok := kv.Get(constant.KVKeyEmailVerificationCode + ":" + req.Email)
|
||||
if !ok || verificationCode != req.VerificationCode {
|
||||
return nil, errs.ErrInvalidCredentials
|
||||
}
|
||||
// 检查用户名或邮箱是否已存在
|
||||
existingUser, err := repo.User.GetByUsernameOrEmail(req.Username)
|
||||
if err != nil {
|
||||
return nil, errs.ErrInternalServer
|
||||
}
|
||||
if existingUser != nil {
|
||||
return nil, errs.New(http.StatusConflict, "Username or email already exists", nil)
|
||||
}
|
||||
// 创建新用户
|
||||
|
||||
newUser := &model.User{
|
||||
Username: req.Username,
|
||||
Nickname: req.Nickname,
|
||||
Email: req.Email,
|
||||
Gender: "",
|
||||
Role: "user",
|
||||
Password: "",
|
||||
}
|
||||
err = repo.User.Create(newUser)
|
||||
if err != nil {
|
||||
return nil, errs.ErrInternalServer
|
||||
}
|
||||
// 生成访问令牌和刷新令牌
|
||||
token := utils.Jwt.NewClaims(newUser.ID, "", false, time.Duration(utils.Env.GetenvAsInt(constant.EnvKeyTokenDuration, 24)*int(time.Hour)))
|
||||
tokenString, err := token.ToString()
|
||||
if err != nil {
|
||||
return nil, errs.ErrInternalServer
|
||||
}
|
||||
refreshToken := utils.Jwt.NewClaims(newUser.ID, utils.Strings.GenerateRandomString(64), true, time.Duration(utils.Env.GetenvAsInt(constant.EnvKeyRefreshTokenDuration, 30)*int(time.Hour)))
|
||||
refreshTokenString, err := refreshToken.ToString()
|
||||
if err != nil {
|
||||
return nil, errs.ErrInternalServer
|
||||
}
|
||||
// 对refresh token进行持久化存储
|
||||
err = repo.Session.SaveSession(refreshToken.SessionKey)
|
||||
if err != nil {
|
||||
return nil, errs.ErrInternalServer
|
||||
}
|
||||
|
||||
resp := &dto.UserRegisterResp{
|
||||
Token: tokenString,
|
||||
RefreshToken: refreshTokenString,
|
||||
User: newUser.ToDto(),
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (s *userService) VerifyEmail(req *dto.VerifyEmailReq) (*dto.VerifyEmailResp, error) {
|
||||
|
@ -24,6 +24,7 @@ func (e *ServiceError) Error() string {
|
||||
var (
|
||||
ErrNotFound = &ServiceError{Code: http.StatusNotFound, Message: "not found"}
|
||||
ErrInvalidCredentials = &ServiceError{Code: http.StatusUnauthorized, Message: "invalid credentials"}
|
||||
ErrConflict = &ServiceError{Code: http.StatusConflict, Message: "resource conflict"}
|
||||
ErrInternalServer = &ServiceError{Code: http.StatusInternalServerError, Message: "internal server error"}
|
||||
ErrBadRequest = &ServiceError{Code: http.StatusBadRequest, Message: "invalid request parameters"}
|
||||
ErrForbidden = &ServiceError{Code: http.StatusForbidden, Message: "access forbidden"}
|
||||
|
Reference in New Issue
Block a user