package handler import ( "encoding/json" "fmt" "github.com/parnurzeal/gorequest" "net/http" "strings" "time" ) // KfzHandler Kfz处理器 type KfzHandler struct { } // NewKfzHandler 创建Kfz处理器实例 func NewKfzHandler() *KfzHandler { return &KfzHandler{} } // KfzLogin 登录孔网并返回用户信息 func (h *KfzHandler) KfzLogin(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(32 << 20) username := r.PostForm.Get("username") password := r.PostForm.Get("password") if username == "" || password == "" { w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"code":500,"message":"username和password不能为空"}`)) return } token, err := outKfzLogin(username, password) if err != nil { w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error()))) return } userInfo, err := outKfzGetUserInfo(token) if err != nil { w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"%s"}`, err.Error()))) return } userInfo.Token = token w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "code": 200, "message": "success", "data": userInfo, }) } /* * 孔网登录 * 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 }