Files
EchoChat/backend/go-service/cmd/server/main.go
bujinyuan d975adaf2a feat(auth): 完整认证系统 — 注册/登录/JWT/路由(Task 4 + Task 5)
Task 4 — 认证服务层:
- pkg/utils/password.go: bcrypt 密码加密与校验
- pkg/utils/jwt.go: Access/Refresh Token 生成与解析(jwt/v5@v5.2.1,兼容 Go 1.23)
- app/dto/auth_dto.go: 认证相关请求/响应 DTO(含参数校验 binding tag)
- app/auth/service/auth_service.go: 核心业务逻辑(注册、登录、管理员登录、Token 刷新、个人信息、改密码)
- pkg/middleware/auth.go: JWT 认证中间件 + 角色权限检查中间件

Task 5 — Controller 与路由注册:
- app/auth/controller/auth_controller.go: 前台认证接口(7 个 API)
- app/auth/controller/admin_auth_controller.go: 后台管理认证接口
- app/auth/router.go: auth 模块路由定义(模块自包含)
- router/router.go: 主路由汇总入口(仅做调度,不含具体路由定义)
- cmd/server/main.go: 路由注册迁移到 router.Setup()

已验证全部接口:注册 ✓ 登录 ✓ 获取 profile ✓ 错误密码 ✓ 未认证拒绝 ✓ 非管理员拒绝 ✓

Made-with: Cursor
2026-02-28 16:42:28 +08:00

95 lines
2.2 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 main 是 EchoChat 后端服务的入口
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/echochat/backend/config"
"github.com/echochat/backend/pkg/logs"
"github.com/echochat/backend/pkg/middleware"
"github.com/echochat/backend/app/provider"
"github.com/echochat/backend/router"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
func main() {
// 1. 加载配置
cfg, err := config.Load("config", "config.dev")
if err != nil {
fmt.Printf("加载配置失败: %v\n", err)
os.Exit(1)
}
// 2. 初始化日志系统
if err := logs.Init(&cfg.Log); err != nil {
fmt.Printf("初始化日志失败: %v\n", err)
os.Exit(1)
}
defer logs.Sync()
ctx := context.Background()
logs.Info(ctx, "main", "EchoChat 服务启动中",
zap.String("mode", cfg.Server.Mode),
zap.Int("port", cfg.Server.Port),
)
// 3. 通过 Wire 初始化所有组件
app, err := provider.InitializeApp(cfg)
if err != nil {
logs.Fatal(ctx, "main", "初始化应用失败", zap.Error(err))
}
// 4. 创建 Gin Engine
if cfg.Server.Mode == "release" {
gin.SetMode(gin.ReleaseMode)
}
engine := gin.New()
// 5. 注册中间件顺序Trace → Logger → CORS → Recovery
engine.Use(
middleware.Trace(),
middleware.Logger(),
middleware.CORS(),
middleware.Recovery(),
)
// 6. 注册路由(由 router.Setup 统一汇总各模块路由)
router.Setup(engine, app)
// 7. 启动 HTTP 服务(优雅关闭)
addr := fmt.Sprintf(":%d", cfg.Server.Port)
srv := &http.Server{
Addr: addr,
Handler: engine,
}
go func() {
logs.Info(ctx, "main", "HTTP 服务启动", zap.String("addr", addr))
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logs.Fatal(ctx, "main", "HTTP 服务启动失败", zap.Error(err))
}
}()
// 等待中断信号,优雅关闭
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logs.Info(ctx, "main", "正在关闭服务...")
shutdownCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
logs.Error(ctx, "main", "服务关闭失败", zap.Error(err))
}
logs.Info(ctx, "main", "服务已停止")
}