Files
schedule_converter/auth/login.go
lafay ab37aeb2fc
All checks were successful
Build / build (push) Successful in 2m17s
refactor: introduce service layer and migrate gRPC handlers to use it
Extract business logic from gRPC handlers into a dedicated service package.
Add context support throughout for cancellation and timeouts. Move models to
their own package, remove hardcoded credentials from config, and simplify
parsers to only handle HTML parsing.
2026-06-16 18:33:13 +08:00

59 lines
1.3 KiB
Go

package auth
import (
"context"
"fmt"
"io"
"log/slog"
"net/http"
"regexp"
"strings"
"schedule_converter/client"
"schedule_converter/config"
)
var nameRegexp = regexp.MustCompile(`(\w+)同学`)
// LoginWithClient 使用指定的 HTTP 客户端和凭据登录。
func LoginWithClient(ctx context.Context, httpClient *http.Client, captchaCode, username, password string) (bool, error) {
log := slog.With("username", username)
log.Debug("执行登录")
data := fmt.Sprintf("usercode=%s&password=%s&code=%s", username, password, captchaCode)
req, err := http.NewRequestWithContext(ctx, "POST", config.Get().BaseURL+"/login", strings.NewReader(data))
if err != nil {
return false, err
}
req.Header = client.GetHeadersWithContentType("application/x-www-form-urlencoded")
resp, err := httpClient.Do(req)
if err != nil {
return false, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return false, err
}
bodyStr := string(body)
if client.CheckLoginSuccess(bodyStr) {
if match := nameRegexp.FindStringSubmatch(bodyStr); len(match) > 1 {
log.Info("登录成功", "name", match[1])
} else {
log.Info("登录成功")
}
return true, nil
}
if client.IsCaptchaError(bodyStr) {
log.Warn("登录失败:验证码错误")
} else {
log.Warn("登录失败")
}
return false, nil
}