Metadata-Version: 2.4
Name: CHUAuthSDK
Version: 1.1.0
Summary: A Python SDK for CHU Central Authentication Service
Author: Rinn
License-Expression: MIT
Project-URL: Homepage, https://github.com/RinnMoe/CHUAuthSDK
Project-URL: Repository, https://github.com/RinnMoe/CHUAuthSDK
Project-URL: Issues, https://github.com/RinnMoe/CHUAuthSDK/issues
Keywords: cas,auth,chu,login,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Requires-Dist: beautifulsoup4>=4.11.0
Requires-Dist: pycryptodome>=3.15.0
Dynamic: license-file

# CHUAuthSDK

CHU统一身份认证 Python SDK

> 废弃说明：根据相关限制，验证码自动识别功能已废弃。本SDK不再依赖 `ddddocr`，亦不会自动识别或完成验证码。

> 基于个资安全以及易触发安全验证之顾虑，不建议使用账密方式登录。


## 安装

### 从 PyPI 安装

```bash
pip install CHUAuthSDK
```

### 本地开发安装

```bash
pip install -r requirements.txt
```

## 快速开始

```python
from CHUAuthSDK import CHUAuth, CaptchaRequiredError, UnboundAccountError

# 创建认证客户端
auth = CHUAuth(cookie_dir="cookies")

try:
    def save_qr(qr_image: bytes) -> None:
        with open("qr_login.png", "wb") as f:
            f.write(qr_image)
        print("请使用微信扫描 qr_login.png")

    # 推荐：微信扫码登录
    session = auth.login_qr(
        service_url="xxx",
        qr_callback=save_qr
    )
    
    # 获取用户信息
    user_info = auth.get_user_info()
    print(f"欢迎, {user_info['cn']}!")
    
    # 使用 session 访问需要认证的资源
    resp = session.get("xxx")
    print(resp.json())
    
except CaptchaRequiredError:
    # 当前验证码形式不再提供图片数据，SDK 仅抛出需要验证码的错误
    print("需要验证码，请使用支持验证码的新登录流程或稍后重试")

except UnboundAccountError:
    print("当前微信未绑定账号，请先完成账号绑定")
    
except Exception as e:
    print(f"登录失败: {e}")
```

## API 文档

### CHUAuth

#### 初始化参数

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `cas_url` | `str` | `xxx` | 统一身份认证服务器地址 |
| `cookie_dir` | `Optional[str]` | `None` | Cookie 存储目录，None 则不持久化。传入目录路径启用持久化，cookie 文件统一存放在该目录下，自动命名为 "cookies_{username}.json"。例如传入 "cookies" 会生成 "cookies/cookies_2021001.json" |

#### 登录方法

SDK 提供四种登录方式。由于相关限制，不再建议使用账密登录，推荐优先使用微信扫码登录。

##### 1. `login_qr(username=None, service_url=None, force_relogin=False, qr_timeout=120, qr_callback=None)`

微信扫码登录。SDK 会从 CAS 登录页中的二维码 iframe 获取微信二维码图片数据，并通过 `qr_callback(bytes)` 传给调用方；保存、显示二维码由调用方完成。

**参数:**
- `username`: 可选账号标识。传入后会优先读取 `cookies_{username}.json`
- `service_url`: 可选业务系统回跳地址
- `force_relogin`: 强制重新扫码登录
- `qr_timeout`: 等待扫码确认的超时时间（秒）
- `qr_callback`: 接收二维码图片 `bytes` 的回调函数

**返回:** `requests.Session` - 已认证的会话对象

**示例:**
```python
auth = CHUAuth(cookie_dir="cookies", verbose=True)

def save_qr(qr_image: bytes) -> None:
    with open("qr_login.png", "wb") as f:
        f.write(qr_image)
    print("请使用微信扫描 qr_login.png")

session = auth.login_qr(
    service_url="xxx",
    qr_timeout=120,
    qr_callback=save_qr
)
```

如果微信尚未绑定账号，扫码确认后会抛出 `UnboundAccountError`。

##### 2. `login(username, password, captcha=None, force_relogin=False)`

直接传入账号密码登录。由于相关限制，不再建议使用该方式；保留该接口仅用于兼容旧流程。

**参数:**
- `username`: 用户名（学工号/手机号）
- `password`: 密码
- `captcha`: 验证码（可选）
- `force_relogin`: 强制重新登录

**返回:** `requests.Session` - 已认证的会话对象

**示例:**
```python
auth = CHUAuth(cookie_dir="cookies")
session = auth.login("2021001", "password")
```

##### 3. `login_interactive()`

CLI 交互式登录，SDK 自动提示用户输入账号密码。由于相关限制，不再建议使用该方式；推荐使用 `login_qr()`。

**返回:** `requests.Session` - 已认证的会话对象

**示例:**
```python
auth = CHUAuth(cookie_dir="cookies")
session = auth.login_interactive()  # 提示输入账号密码
```

##### 4. `login_batch(accounts_json)`

批量登录多个账号。该方法仍基于账密登录；由于相关限制，不再建议使用。

**参数:**
- `accounts_json`: JSON 字符串或 JSON 文件路径
  ```json
  [
    {"username": "2021001", "password": "password1"},
    {"username": "2021002", "password": "password2"}
  ]
  ```

**返回:** `Dict[str, Any]` - 登录结果字典
```python
{
    "2021001": {"success": True, "session": <Session>, "error": None},
    "2021002": {"success": False, "session": None, "error": "密码错误"}
}
```

**示例:**
```python
auth = CHUAuth(cookie_dir="cookies")

# 传入 JSON 字符串
results = auth.login_batch('[{"username": "2021001", "password": "pwd"}]')

# 或传入 JSON 文件路径
results = auth.login_batch("accounts.json")
```

#### 其他方法

##### `get_user_info()`

获取当前用户信息。

**返回:** `Dict[str, Any]` - 用户信息字典

##### `get_cookies_dict()`

获取 cookies 字典。

**返回:** `Dict[str, str]`

##### `get_session_id()`

获取 session ID。

**返回:** `Optional[str]`

##### `logout()`

登出并清除会话。

### 异常

#### `AuthError`

认证失败异常基类。

#### `CaptchaRequiredError`

需要验证码异常。该异常不携带验证码图片数据。

#### `QRCodeError`

二维码登录相关异常。

#### `UnboundAccountError`

微信扫码成功但未绑定账号时抛出，继承自 `QRCodeError`。


## License

MIT
