package logic import ( "context" "database/sql" "errors" "godemo/user/internal/model" "godemo/user/internal/svc" "godemo/user/user" "time" "github.com/golang-jwt/jwt/v4" "github.com/zeromicro/go-zero/core/logx" "golang.org/x/crypto/bcrypt" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) type LoginLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger } func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic { return &LoginLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *LoginLogic) Login(in *user.LoginRequest) (*user.LoginResponse, error) { // 1. 查找用户 var u model.User err := l.svcCtx.DB.Get(&u, "SELECT * FROM users WHERE username = $1", in.Username) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, status.Error(codes.NotFound, "用户不存在") } return nil, status.Error(codes.Internal, err.Error()) } // 2. 校验密码(假设密码已加密存储) err = bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(in.Password)) if err != nil { return nil, status.Error(codes.Unauthenticated, "密码错误") } // 3. 签发 JWT Token claims := jwt.MapClaims{ "sub": u.UserId, "exp": time.Now().Add(time.Minute * 15).Unix(), // 默认 15 分钟有效期 "iat": time.Now().Unix(), "roles": u.Roles, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) signedToken, err := token.SignedString([]byte(l.svcCtx.Config.JwtAuth.AccessSecret)) if err != nil { return nil, status.Error(codes.Unavailable, "token生成失败") } // 4. 返回响应 return &user.LoginResponse{ Token: signedToken, ExpiresAt: claims["exp"].(int64), }, nil }