Skip to content

密碼管理

在 Potato 中配置 PBKDF2-SHA256 密碼雜湊、管理員 CLI/API 重置、使用者自助的令牌重置流程,以及 SQLite 或 PostgreSQL 憑據儲存。

v2.4.0 新增

Potato 的認證系統使用 PBKDF2-SHA256,迭代 10 萬次,併為每個使用者生成獨立的 salt —— 這也是 NIST 推薦的密碼儲存做法。本頁介紹密碼如何儲存、如何重置,以及如何讓憑據在伺服器重啟後依然有效。

安全實現

密碼以 salt$hash 格式儲存:

  • 32 個十六進位制字元的 salt,每個使用者各不相同
  • salt + password 的 SHA-256 雜湊,64 個字元
  • 通過 hmac.compare_digest 做常數時間比較,防止時序攻擊

如果 user_config.jsonl 檔案裡還存著明文密碼,Potato 載入時會自動用新的 salt 重新雜湊,不需要手動遷移。

預設配置

預設情況下 Potato 使用記憶體認證,標註者必須寫在配置裡:

yaml
authentication:
  method: in_memory
  require_password: true
 
user_config:
  users:
    - username: "annotator1"
      password: "initial-password"   # will be hashed on first load
    - username: "annotator2"
      password: "initial-password"

持久化憑據

記憶體中的憑據重啟後就沒了。要持久儲存,用檔案或資料庫後端。

基於檔案的持久化

yaml
authentication:
  method: in_memory
  user_config_path: /shared/path/to/user_config.jsonl

Potato 會把雜湊後的憑據寫進這個檔案,重啟時再讀回來 —— 會話期間設定或修改的密碼可以跨重啟保留。

資料庫後端

SQLite(不需要額外依賴):

yaml
authentication:
  method: database
  database_url: "sqlite:///auth/users.db"

PostgreSQL(需要 psycopg2-binary):

yaml
authentication:
  method: database
  database_url: "postgresql://user:password@localhost:5432/potato_auth"

資料庫表會在首次啟動時自動建立。

注意: method: databaseuser_config_path 互斥,只能選一種持久化方式。

重置密碼

管理員 CLI

從命令列重置密碼:

bash
# Reset a specific user's password
potato reset-password config.yaml --username annotator1
 
# Prompted for new password interactively

管理員 API

用 API key 以程式方式重置:

bash
curl -X POST http://localhost:8000/admin/reset_password \
  -H "X-API-Key: $ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"username": "annotator1", "new_password": "new-secure-password"}'

使用者自助的令牌重置

Potato 支援由使用者發起的重置流程。使用者訪問 /forgot-password,輸入使用者名稱,拿到一個一次性的重置令牌,再訪問 /reset/<token> 設定新密碼。

令牌有效期為 24 小時,且只能使用一次。Potato 不發郵件,重置連結由管理員手動發給使用者。

在配置中啟用:

yaml
authentication:
  method: database
  database_url: "sqlite:///auth/users.db"
  allow_password_reset: true
  reset_token_ttl_hours: 24

管理員操作流程:

bash
# Generate a reset token for a user
curl -X POST http://localhost:8000/admin/generate_reset_token \
  -H "X-API-Key: $ADMIN_API_KEY" \
  -d '{"username": "annotator1"}'
 
# Returns: {"reset_url": "https://your-server.com/reset/abc123..."}
# Share this URL with the annotator

免密模式

課堂演示、快速小規模研究,或者使用外部認證(MTurk、Prolific)的任務,可以完全關掉密碼:

yaml
authentication:
  method: in_memory
  require_password: false

標註者輸入任意使用者名稱即可登入,不會出現密碼輸入框。涉及敏感資料或需要確認身份的任務不建議這麼做。

詳見免密登入

完整參考

yaml
authentication:
  method: in_memory       # in_memory | database | oauth | clerk
 
  # In-memory options
  require_password: true
  user_config_path: path/to/users.jsonl   # optional persistence
 
  # Database options (mutually exclusive with user_config_path)
  database_url: "sqlite:///auth/users.db"
 
  # Self-service reset
  allow_password_reset: true
  reset_token_ttl_hours: 24
 
user_config:
  users:
    - username: "researcher"
      password: "secure-passphrase"
      role: admin
    - username: "annotator1"
      password: "initial-pass"
      role: annotator

延伸閱讀

有關實現詳情,請參閱源文件