329 lines
8.1 KiB
Go
329 lines
8.1 KiB
Go
package provider
|
||
|
||
import (
|
||
"context"
|
||
"time"
|
||
|
||
appErrors "github.com/topfans/backend/pkg/errors"
|
||
"github.com/topfans/backend/pkg/logger"
|
||
pbCommon "github.com/topfans/backend/pkg/proto/common"
|
||
pb "github.com/topfans/backend/pkg/proto/user"
|
||
"github.com/topfans/backend/services/userService/service"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
// AuthProvider 认证Provider实现
|
||
type AuthProvider struct {
|
||
authService service.AuthService
|
||
}
|
||
|
||
// getClientIP 从 context 中获取客户端 IP(简化实现)
|
||
func getClientIP(ctx context.Context) string {
|
||
// 在实际部署中,应从网关传递的 attachments 或 header 中获取
|
||
// 这里返回一个默认值让代码能编译通过
|
||
return "127.0.0.1"
|
||
}
|
||
|
||
// NewAuthProvider 创建认证Provider实例
|
||
func NewAuthProvider(authService service.AuthService) *AuthProvider {
|
||
return &AuthProvider{
|
||
authService: authService,
|
||
}
|
||
}
|
||
|
||
// Register 用户注册
|
||
func (p *AuthProvider) Register(ctx context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received Register request",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Int64("star_id", req.StarId),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.authService.Register(ctx, req)
|
||
if err != nil {
|
||
logger.Logger.Error("Register failed",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.RegisterResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0, // 时间戳将在Service层设置
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("Register successful",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Int64("user_id", resp.User.Id),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// Login 用户登录
|
||
func (p *AuthProvider) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received Login request",
|
||
zap.String("mobile", req.Mobile),
|
||
)
|
||
|
||
// 调用Service层
|
||
resp, err := p.authService.Login(req)
|
||
if err != nil {
|
||
logger.Logger.Error("Login failed",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.LoginResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0, // 时间戳将在Service层设置
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("Login successful",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Int64("user_id", resp.User.Id),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// Logout 用户登出
|
||
func (p *AuthProvider) Logout(ctx context.Context, req *pb.LogoutRequest) (*pb.LogoutResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received Logout request")
|
||
|
||
// 从 attachments 获取用户信息(网关已验证 Token)
|
||
userID, _, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.LogoutResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}, nil
|
||
}
|
||
|
||
logger.Logger.Info("Extracted user info from attachments",
|
||
zap.Int64("user_id", userID),
|
||
)
|
||
|
||
// 调用Service层(传递 userID)
|
||
resp, err := p.authService.Logout(userID)
|
||
if err != nil {
|
||
logger.Logger.Error("Logout failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.LogoutResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0, // 时间戳将在Service层设置
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("Logout successful",
|
||
zap.Int64("user_id", userID),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// RefreshToken 刷新Token
|
||
func (p *AuthProvider) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequest) (*pb.RefreshTokenResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Info("Received RefreshToken request")
|
||
|
||
// 从 attachments 获取用户信息(网关已验证 Token)
|
||
userID, starID, err := extractUserInfoFromDubboAttachments(ctx)
|
||
if err != nil {
|
||
logger.Logger.Error("Failed to extract user info from attachments",
|
||
zap.Error(err),
|
||
)
|
||
return &pb.RefreshTokenResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_UNAUTHORIZED,
|
||
Message: err.Error(),
|
||
Timestamp: 0,
|
||
},
|
||
}, nil
|
||
}
|
||
|
||
logger.Logger.Info("Extracted user info from attachments",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
// 调用Service层(传递 userID 和 starID)
|
||
resp, err := p.authService.RefreshToken(userID, starID)
|
||
if err != nil {
|
||
logger.Logger.Error("RefreshToken failed",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.RefreshTokenResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0, // 时间戳将在Service层设置
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Info("RefreshToken successful",
|
||
zap.Int64("user_id", userID),
|
||
zap.Int64("star_id", starID),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// ValidateToken 验证Token
|
||
func (p *AuthProvider) ValidateToken(ctx context.Context, req *pb.ValidateTokenRequest) (*pb.ValidateTokenResponse, error) {
|
||
// 记录请求日志
|
||
logger.Logger.Debug("Received ValidateToken request")
|
||
|
||
// 调用Service层
|
||
resp, err := p.authService.ValidateToken(req)
|
||
if err != nil {
|
||
logger.Logger.Error("ValidateToken failed",
|
||
zap.Error(err),
|
||
)
|
||
|
||
// 如果响应为空,构建错误响应
|
||
if resp == nil {
|
||
resp = &pb.ValidateTokenResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: 0, // 时间戳将在Service层设置
|
||
},
|
||
}
|
||
}
|
||
|
||
return resp, err
|
||
}
|
||
|
||
logger.Logger.Debug("ValidateToken successful",
|
||
zap.Bool("is_valid", resp.IsValid),
|
||
zap.Int64("user_id", resp.UserId),
|
||
)
|
||
|
||
return resp, nil
|
||
}
|
||
|
||
// SendCode 发送验证码
|
||
func (p *AuthProvider) SendCode(ctx context.Context, req *pb.SendCodeRequest) (*pb.SendCodeResponse, error) {
|
||
logger.Logger.Info("Received SendCode request",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.String("scene", req.Scene),
|
||
)
|
||
|
||
// 获取客户端IP(从context或 attachments 获取)
|
||
ip := getClientIP(ctx)
|
||
|
||
expiresIn, err := service.SendVerificationCode(ctx, req.Mobile, ip)
|
||
if err != nil {
|
||
logger.Logger.Error("SendCode failed",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Error(err),
|
||
)
|
||
return &pb.SendCodeResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: time.Now().UnixMilli(),
|
||
},
|
||
}, nil
|
||
}
|
||
|
||
logger.Logger.Info("SendCode successful",
|
||
zap.String("mobile", req.Mobile),
|
||
)
|
||
|
||
return &pb.SendCodeResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_OK,
|
||
Message: "发送成功",
|
||
Timestamp: time.Now().UnixMilli(),
|
||
},
|
||
ExpiresIn: int32(expiresIn),
|
||
}, nil
|
||
}
|
||
|
||
// VerifyCode 验证验证码
|
||
func (p *AuthProvider) VerifyCode(ctx context.Context, req *pb.VerifyCodeRequest) (*pb.VerifyCodeResponse, error) {
|
||
logger.Logger.Info("Received VerifyCode request",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.String("scene", req.Scene),
|
||
)
|
||
|
||
token, err := service.VerifyCode(ctx, req.Mobile, req.Code)
|
||
if err != nil {
|
||
logger.Logger.Warn("VerifyCode failed",
|
||
zap.String("mobile", req.Mobile),
|
||
zap.Error(err),
|
||
)
|
||
return &pb.VerifyCodeResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: appErrors.ToStatusCode(err),
|
||
Message: err.Error(),
|
||
Timestamp: time.Now().UnixMilli(),
|
||
},
|
||
Verified: false,
|
||
}, nil
|
||
}
|
||
|
||
logger.Logger.Info("VerifyCode successful",
|
||
zap.String("mobile", req.Mobile),
|
||
)
|
||
|
||
return &pb.VerifyCodeResponse{
|
||
Base: &pbCommon.BaseResponse{
|
||
Code: pbCommon.StatusCode_STATUS_OK,
|
||
Message: "验证成功",
|
||
Timestamp: time.Now().UnixMilli(),
|
||
},
|
||
Verified: true,
|
||
VerifyToken: token,
|
||
ExpiresIn: 300,
|
||
}, nil
|
||
}
|