226 lines
6.4 KiB
Go
226 lines
6.4 KiB
Go
package handler
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/parnurzeal/gorequest"
|
|
)
|
|
|
|
// KfzHandler Kfz处理器
|
|
type KfzHandler struct {
|
|
}
|
|
|
|
// NewKfzHandler 创建Kfz处理器实例
|
|
func NewKfzHandler() *KfzHandler {
|
|
return &KfzHandler{}
|
|
}
|
|
|
|
// KfzLogin 登录孔网并返回用户信息
|
|
func (h *KfzHandler) KfzLogin(w http.ResponseWriter, r *http.Request) {
|
|
clientIP := r.RemoteAddr
|
|
if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
|
|
clientIP = forwarded
|
|
}
|
|
log.Printf("[KfzLogin] 收到登录请求, 来源IP: %s", clientIP)
|
|
|
|
r.ParseMultipartForm(32 << 20)
|
|
username := r.PostForm.Get("username")
|
|
password := r.PostForm.Get("password")
|
|
|
|
if username == "" || password == "" {
|
|
log.Printf("[KfzLogin] username或password为空, 来源IP: %s", clientIP)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(`{"code":500,"message":"username和password不能为空"}`))
|
|
return
|
|
}
|
|
|
|
log.Printf("[KfzLogin] 开始登录孔网, username=%s, 来源IP: %s", username, clientIP)
|
|
token, err := outKfzLogin(username, password)
|
|
if err != nil {
|
|
log.Printf("[KfzLogin] 孔网登录失败: username=%s, 错误=%v, 来源IP: %s", username, err, clientIP)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
|
|
return
|
|
}
|
|
log.Printf("[KfzLogin] 孔网登录成功: username=%s, token=%s..., 来源IP: %s", username, token[:min(len(token), 10)], clientIP)
|
|
|
|
userInfo, err := outKfzGetUserInfo(token)
|
|
if err != nil {
|
|
log.Printf("[KfzLogin] 获取用户信息失败: username=%s, 错误=%v, 来源IP: %s", username, err, clientIP)
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error())))
|
|
return
|
|
}
|
|
|
|
userInfo.Token = token
|
|
log.Printf("[KfzLogin] 登录成功: username=%s, userId=%d, nickname=%s, 来源IP: %s", username, userInfo.UserID, userInfo.Nickname, clientIP)
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"code": 200,
|
|
"message": "success",
|
|
"data": userInfo,
|
|
})
|
|
}
|
|
|
|
func min(a, b int) int {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|
|
|
|
/*
|
|
* 孔网登录
|
|
* param username[string] 孔网用户名
|
|
* param password[string] 孔网密码
|
|
* return token,错误信息
|
|
* Error 登录请求失败
|
|
* Error 登录失败(HTTP状态码: %d)
|
|
* Error 登录成功但未获取到Cookie
|
|
* Error 登录失败: 未找到 PHPSESSID
|
|
* Error 账号或密码错误
|
|
* Error 登录失败
|
|
* Error 登录失败,未知错误!
|
|
*/
|
|
func outKfzLogin(username, password string) (string, error) {
|
|
// 检查用户名和密码是否为空
|
|
if username == "" || password == "" {
|
|
return "", fmt.Errorf("请输入用户名和密码!")
|
|
}
|
|
|
|
// 准备POST请求的表单数据
|
|
formData := map[string]string{
|
|
"loginName": username,
|
|
"loginPass": password,
|
|
"returnUrl": "http://user.kongfz.com/",
|
|
}
|
|
// 孔网登录URL
|
|
loginUrl := "https://login.kongfz.com/Pc/Login/account"
|
|
|
|
// 发送登录请求
|
|
resp, body, errs := gorequest.New().
|
|
Post(loginUrl).
|
|
Set("Content-Type", "application/x-www-form-urlencoded").
|
|
Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36").
|
|
Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8").
|
|
Send(formData).
|
|
Timeout(15 * time.Second).
|
|
End()
|
|
|
|
// 请求错误处理
|
|
if len(errs) > 0 {
|
|
return "", fmt.Errorf("登录请求失败: %v", errs)
|
|
}
|
|
|
|
// 检查HTTP状态码
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", fmt.Errorf("登录失败(HTTP状态码: %d)", resp.StatusCode)
|
|
}
|
|
|
|
// 提取Cookie
|
|
cookie := resp.Header.Get("Set-Cookie")
|
|
// 检查是否登录成功(通过响应内容判断)
|
|
if strings.Contains(body, "window.location.href='https://login.kongfz.cn/Pc/Session/rsync") {
|
|
if cookie == "" {
|
|
return "", fmt.Errorf("登录成功但未获取到Cookie")
|
|
}
|
|
|
|
// 登录成功
|
|
if strings.Contains(cookie, "PHPSESSID=") {
|
|
token := strings.Split(strings.Split(cookie, "PHPSESSID=")[1], ";")[0]
|
|
return token, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("登录失败: 未找到PHPSESSID")
|
|
}
|
|
|
|
// 错误信息
|
|
var res struct {
|
|
Status bool `json:"status"`
|
|
ErrCode int `json:"errCode"`
|
|
ErrInfo string `json:"errInfo"`
|
|
}
|
|
// 解析json
|
|
if err := json.Unmarshal([]byte(body), &res); err == nil {
|
|
if res.ErrCode == 1001 || res.ErrCode == 1005 {
|
|
return "", fmt.Errorf("账号或密码错误!")
|
|
}
|
|
|
|
if res.ErrInfo != "" {
|
|
return "", fmt.Errorf("登录失败: %s", res.ErrInfo)
|
|
}
|
|
}
|
|
|
|
return "", fmt.Errorf("登录失败,未知错误!")
|
|
}
|
|
|
|
// UserInfo 孔网用户信息结构体
|
|
type UserInfo struct {
|
|
UserID int64 `json:"userId"` // 用户ID
|
|
Nickname string `json:"nickname"` // 用户昵称
|
|
Mobile string `json:"mobile"` // 手机号
|
|
Token string `json:"token"` // token
|
|
}
|
|
|
|
/*
|
|
* 获取孔网用户信息
|
|
* param token[string] 孔网token
|
|
* return 孔网用户信息结构体,错误信息
|
|
* Error 查询请求失败
|
|
* Error HTTP错误
|
|
* Error 解析JSON失败
|
|
* Error 获取用户失败
|
|
*/
|
|
func outKfzGetUserInfo(token string) (*UserInfo, error) {
|
|
// 用户信息URL
|
|
url := "https://user.kongfz.com/User/Index/getUserInfo/"
|
|
|
|
// 发送请求
|
|
resp, body, errs := gorequest.New().
|
|
Get(url).
|
|
Set("Cookie", fmt.Sprintf("PHPSESSID=%s", token)).
|
|
Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36").
|
|
Set("Accept", "application/json, text/plain, */*").
|
|
Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8").
|
|
Timeout(15 * time.Second).
|
|
End()
|
|
if len(errs) > 0 {
|
|
return nil, fmt.Errorf("查询用户信息请求失败: %v", errs)
|
|
}
|
|
|
|
//检查HTTP状态码
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("HTTP错误: %s", resp.Status)
|
|
}
|
|
|
|
// 响应数据
|
|
var userInfo struct {
|
|
Status bool `json:"status"`
|
|
Data struct {
|
|
UserID int64 `json:"userId"`
|
|
Nickname string `json:"nickname"`
|
|
Mobile string `json:"mobile"`
|
|
}
|
|
}
|
|
// 解析json
|
|
if err := json.Unmarshal([]byte(body), &userInfo); err != nil {
|
|
return nil, fmt.Errorf("解析JSON失败: %w", err)
|
|
}
|
|
|
|
// 创建用户信息对象
|
|
user := &UserInfo{}
|
|
if !userInfo.Status {
|
|
return nil, fmt.Errorf("获取用户失败!")
|
|
}
|
|
user.UserID = userInfo.Data.UserID
|
|
user.Nickname = userInfo.Data.Nickname
|
|
user.Mobile = userInfo.Data.Mobile
|
|
return user, nil
|
|
}
|