v1.0
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
import hashlib
|
||||
import requests
|
||||
from flask import session, redirect, url_for, request
|
||||
from functools import wraps
|
||||
|
||||
LOGIN_URL = "https://api.infi.cn/board/user/nc/accountLogin"
|
||||
USER_API = "https://api.infi.cn/bsg/user/getMyInfo"
|
||||
|
||||
def infi_login(account, password):
|
||||
"""使用英飞API登录"""
|
||||
try:
|
||||
login_data = {
|
||||
"account": account,
|
||||
"passwd": hashlib.md5(password.encode()).hexdigest(),
|
||||
"loginOriginType": 1
|
||||
}
|
||||
|
||||
login_response = requests.post(
|
||||
LOGIN_URL,
|
||||
json=login_data,
|
||||
headers={"Content-Type": "application/json"},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
print(f"[debug] infi_login: LOGIN_URL status={login_response.status_code}")
|
||||
print(f"[debug] infi_login: LOGIN_URL body={login_response.text[:1000]}")
|
||||
|
||||
if login_response.status_code != 200:
|
||||
return None, f"API请求失败,HTTP {login_response.status_code}"
|
||||
|
||||
try:
|
||||
data = login_response.json()
|
||||
except ValueError:
|
||||
print("[debug] infi_login: 无法解析登录响应为 JSON", login_response.text[:1000])
|
||||
return None, "无法解析登录响应为 JSON"
|
||||
|
||||
# 兼容不同的返回格式:优先从 obj.token 拿 token,其次尝试顶层 token 或 obj 为字符串的情况
|
||||
token = None
|
||||
if isinstance(data, dict):
|
||||
obj = data.get('obj')
|
||||
if isinstance(obj, dict) and obj.get('token'):
|
||||
token = obj.get('token')
|
||||
elif isinstance(obj, str) and obj:
|
||||
token = obj
|
||||
elif data.get('token'):
|
||||
token = data.get('token')
|
||||
|
||||
if not token:
|
||||
# 如果存在 code/msg,把它们返回以便排查
|
||||
code = data.get('code') if isinstance(data, dict) else None
|
||||
msg = data.get('msg') if isinstance(data, dict) else None
|
||||
detail = f" code={code}" if code is not None else ""
|
||||
print(f"[debug] infi_login: 未找到 token,响应 data={data}")
|
||||
if msg:
|
||||
return None, f"登录失败: {msg}{detail}"
|
||||
return None, f"登录失败:未在响应中找到 token。响应: {data}"
|
||||
|
||||
# 获取用户信息
|
||||
user_response = requests.post(
|
||||
USER_API,
|
||||
headers={
|
||||
"access-token": token,
|
||||
"Origin": "https://infi.cn",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
timeout=10
|
||||
)
|
||||
|
||||
print(f"[debug] infi_login: USER_API status={user_response.status_code}")
|
||||
print(f"[debug] infi_login: USER_API body={user_response.text[:1000]}")
|
||||
|
||||
if user_response.status_code != 200:
|
||||
body = user_response.text[:1000]
|
||||
return None, f"获取用户信息失败,HTTP {user_response.status_code} 响应: {body}"
|
||||
|
||||
try:
|
||||
user_data = user_response.json()
|
||||
except ValueError:
|
||||
print("[debug] infi_login: 无法解析用户信息响应为 JSON", user_response.text[:1000])
|
||||
return None, "无法解析用户信息响应为 JSON"
|
||||
|
||||
# 兼容不同返回格式:服务端有时使用 code==0 表示成功
|
||||
if isinstance(user_data, dict) and user_data.get('code') is not None and user_data.get('code') not in (0, 200):
|
||||
print(f"[debug] infi_login: user_data indicates failure: {user_data}")
|
||||
return None, f"获取用户信息失败: {user_data.get('msg', '')} 响应: {user_data}"
|
||||
|
||||
user_obj = None
|
||||
if isinstance(user_data, dict):
|
||||
user_obj = user_data.get('obj') or user_data
|
||||
|
||||
return {
|
||||
'token': token,
|
||||
'user_info': user_obj
|
||||
}, None
|
||||
|
||||
except Exception as e:
|
||||
# 针对网络/DNS 解析类错误返回更有帮助的提示
|
||||
msg = str(e)
|
||||
if 'NameResolutionError' in msg or 'Failed to resolve' in msg or 'Max retries exceeded' in msg:
|
||||
return None, (
|
||||
"网络错误:无法解析 api.infi.cn(DNS)。请检查网络连接、DNS 或代理设置。"
|
||||
" 可尝试命令:\n 1) `nslookup api.infi.cn`\n 2) `ping api.infi.cn`\n"
|
||||
" 或切换网络/使用 VPN、设置正确的 `HTTP(S)_PROXY` 环境变量。"
|
||||
)
|
||||
return None, f"登录异常: {msg}"
|
||||
|
||||
def login_required(f):
|
||||
"""登录装饰器"""
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
if 'user_account' not in session:
|
||||
return redirect(url_for('login'))
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
Reference in New Issue
Block a user