Skip to main content

这是一套适合Python快速开发的身份管理模块,SoulSeal 取自修仙小说中的「灵魂烙印」。

Project description

SoulSeal

这是适合Python+FastAPI快速集成的身份管理模块,SoulSeal 取自修仙小说中的「灵魂烙印」。模块内部使用了免安装的键值数据库 RocksDB 来高效存取用户数据。

安装

# 使用pip安装
pip install soulseal

# 或使用Poetry安装(推荐)
poetry add soulseal

快速开始

作为独立服务启动

这种方式非常适合你验证 API 的使用方式。

# 直接使用Python模块运行
poetry run python -m soulseal

# 指定主机和端口
poetry run python -m soulseal --host 0.0.0.0 --port 8080

# 使用环境变量配置
SOULSEAL_DATA_DIR=/path/to/data SOULSEAL_PORT=8080 poetry run python -m soulseal

命令行参数

参数 环境变量 说明 默认值
--data-dir SOULSEAL_DATA_DIR 数据目录 ~/.soulseal
--host SOULSEAL_HOST 主机地址 127.0.0.1
--port SOULSEAL_PORT 端口 8000
--prefix SOULSEAL_PREFIX API前缀 /api
--cors-origins SOULSEAL_CORS_ORIGINS CORS源列表(逗号分隔) http://localhost:3000,...

设计理念

SoulSeal 采用现代化的身份认证架构设计:

  1. JWT身份验证:使用行业标准的JWT令牌进行身份验证和授权
  2. 令牌分离设计
    • 访问令牌(Access Token):短期有效(默认5分钟),存储在内存中,用于API请求认证
    • 刷新令牌(Refresh Token):长期有效(默认7天),存储在HTTP-only Cookie中,用于获取新的访问令牌
  3. 无感续订机制:当访问令牌剩余有效期低于25%时,系统自动续订令牌
  4. 黑名单机制:支持令牌撤销,即使令牌未过期也能立即失效
  5. 多设备支持:同一用户可在多设备同时登录,每个设备使用独立的令牌
  6. 内置用户管理:集成了简单的用户管理模块
  7. 基于角色的访问控制:支持细粒度的权限管理

API端点

SoulSeal提供以下API端点(假设前缀为/api):

路径 方法 描述 授权
/api/auth/register POST 用户注册
/api/auth/login POST 用户登录
/api/auth/logout POST 用户退出
/api/auth/change-password POST 修改密码
/api/auth/profile GET/POST 获取/更新用户信息
/api/auth/refresh-token POST 刷新访问令牌(令牌过期时)

在FastAPI应用中集成

推荐集成方式

下面展示如何在自己控制的FastAPI应用中集成SoulSeal认证功能:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pathlib import Path
from voidring import IndexedRocksDB
from soulseal import TokenSDK, UsersManager, mount_auth_api

# 创建自己的FastAPI应用
app = FastAPI(
    title="我的应用",
    description="集成SoulSeal认证的API",
    version="0.1.0"
)

# 配置CORS(如果前端与后端跨域就必须设置)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
    expose_headers=["Authorization"]  # 确保前端可以获取到Authorization头
)

# 初始化数据库和认证组件
db_path = Path.home() / ".myapp" / "db"
db_path.mkdir(parents=True, exist_ok=True)
db = IndexedRocksDB(str(db_path))

# 创建令牌SDK和用户管理器
token_sdk = TokenSDK(db=db)
users_manager = UsersManager(db)

# 挂载SoulSeal认证API
mount_auth_api(
    app=app,
    prefix="/api",
    token_sdk=token_sdk,
    users_manager=users_manager
)

保护路由的方法

SoulSeal提供了多种方式来保护您的API路由,让您可以根据需求选择最合适的方法:

方法1: 安全路由装饰器(最简洁)

from fastapi import FastAPI, APIRouter
from soulseal import TokenSDK

app = FastAPI()
router = APIRouter()
token_sdk = TokenSDK(db=db)

# 基本认证路由
@token_sdk.secure_route(router, "/secure-route")
async def secure_endpoint():
    return {"message": "此路由受到保护"}

# 需要管理员角色的路由
@token_sdk.secure_route(
    router, 
    "/admin-route", 
    methods=["GET", "POST"],  # 可指定多种HTTP方法
)
async def admin_endpoint(token_claims: dict):
    # token_claims包含用户信息
    return {"message": f"您好,{token_claims.get('username')}"}

# 注册路由
app.include_router(router)

方法2: 使用依赖注入(传统方式)

from fastapi import Depends

# 创建认证依赖
require_user = token_sdk.get_auth_dependency()
require_admin = token_sdk.get_auth_dependency(require_roles=["admin"])

# 基本认证
@router.get(
    "/secure-dependency", 
    openapi_extra={"security": [{"Bearer": []}]}
)
async def secure_with_dependency(user = Depends(require_user)):
    return {"message": f"您好,{user.get('username')}"}

# 管理员认证
@router.get(
    "/admin-dependency", 
    openapi_extra={"security": [{"Bearer": []}]}
)
async def admin_with_dependency(user = Depends(require_admin)):
    return {"message": "管理员专属内容"}

方法3: 编程式注册(适合批量路由)

from soulseal.start import register_secure_route

async def dynamic_endpoint(token_claims: dict = None):
    """动态创建的受保护端点"""
    return {"message": f"您已通过认证,用户ID: {token_claims.get('user_id')}"}

# 注册安全路由
register_secure_route(
    app=app,
    path="/api/dynamic-route",
    endpoint=dynamic_endpoint,
    require_user=token_sdk.get_auth_dependency(),
    methods=["GET"],
    tags=["动态路由"]
)

完整后端演示效果

您可以在启用示例路由的情况下启动应用,查看完整的使用方式:

from soulseal import create_app

app = create_app(
    db_path="./data",
    title="SoulSeal演示",
    description="身份认证系统演示",
    cors_origins=["http://localhost:3000"],
    prefix="/api",
    include_examples=True  # 启用示例路由
)

这将添加以下示例路由:

  • /api/examples/secure-route - 使用安全路由装饰器
  • /api/examples/admin-route - 需要管理员权限(依赖项方式)
  • /api/examples/admin-dependency - 需要管理员权限(直接依赖方式)
  • /api/examples/secure-dependency - 使用依赖注入
  • /api/examples/secure-programmatic - 以编程方式注册的路由

客户端使用

// auth.js - 认证服务
const auth = {
  token: localStorage.getItem('auth_token'),
  
  // 登录并保存令牌
  async login(username, password) {
    const response = await fetch('/api/auth/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password }),
      credentials: 'include'
    });
    
    if (!response.ok) throw new Error('登录失败');
    
    // 保存令牌
    const authHeader = response.headers.get('Authorization');
    if (authHeader?.startsWith('Bearer ')) {
      this.token = authHeader.substring(7);
      localStorage.setItem('auth_token', this.token);
    }
    
    return await response.json();
  },
  
  // 创建带认证的请求
  async fetch(url, options = {}) {
    // 添加认证头
    const headers = { ...options.headers };
    if (this.token) {
      headers['Authorization'] = `Bearer ${this.token}`;
    }
    
    // 发送请求
    const response = await fetch(url, {
      ...options,
      headers,
      credentials: 'include'
    });
    
    // 处理自动令牌续订
    const newToken = response.headers.get('Authorization');
    if (newToken?.startsWith('Bearer ')) {
      this.token = newToken.substring(7);
      localStorage.setItem('auth_token', this.token);
    }
    
    // 处理401错误(令牌过期)
    if (response.status === 401) {
      // 尝试刷新令牌
      const refreshed = await this.refreshToken();
      if (refreshed) {
        // 使用新令牌重试请求
        return this.fetch(url, options);
      } else {
        // 刷新失败,重定向到登录页
        this.logout();
        location.href = '/login';
      }
    }
    
    return response;
  },
  
  // 刷新令牌
  async refreshToken() {
    try {
      const response = await fetch('/api/auth/refresh-token', {
        method: 'POST',
        credentials: 'include'
      });
      
      if (!response.ok) return false;
      
      const data = await response.json();
      if (data.access_token) {
        this.token = data.access_token;
        localStorage.setItem('auth_token', this.token);
        return true;
      }
      return false;
    } catch (e) {
      return false;
    }
  },
  
  // 注销
  logout() {
    fetch('/api/auth/logout', {
      method: 'POST',
      headers: this.token ? { 'Authorization': `Bearer ${this.token}` } : {},
      credentials: 'include'
    }).finally(() => {
      this.token = null;
      localStorage.removeItem('auth_token');
    });
  }
};

// 使用示例
async function getUserProfile() {
  const response = await auth.fetch('/api/auth/profile');
  if (response.ok) {
    const profile = await response.json();
    console.log('用户信息:', profile);
    return profile;
  }
  return null;
}

用户管理功能

SoulSeal提供完整的用户管理功能:

  1. 用户注册与登录:支持用户名、密码和电子邮件注册,密码加密存储
  2. 多设备支持:同一用户可以在多个设备上同时登录,互不干扰
  3. 基于角色的访问控制:支持用户角色设置(用户、管理员等)
  4. 个人资料管理:查看和更新用户信息
  5. 密码管理:支持修改密码、密码重置等功能
  6. 会话管理:查看当前登录设备,可以远程注销特定设备
  7. 账号锁定与激活:管理员可锁定或激活用户账号

安全注意事项

  1. 默认情况下,访问令牌有效期为5分钟,刷新令牌有效期为7天
  2. 访问令牌通过Authorization头部传输,刷新令牌存储在HTTP-only Cookie中,增强安全性
  3. 所有密码均使用bcrypt加密存储,无法还原
  4. 令牌撤销后会被加入黑名单,即使未过期也无法使用
  5. 支持HTTPS,生产环境必须启用

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

soulseal-0.1.12.tar.gz (30.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

soulseal-0.1.12-py3-none-any.whl (36.6 kB view details)

Uploaded Python 3

File details

Details for the file soulseal-0.1.12.tar.gz.

File metadata

  • Download URL: soulseal-0.1.12.tar.gz
  • Upload date:
  • Size: 30.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.0 CPython/3.11.7 Darwin/24.3.0

File hashes

Hashes for soulseal-0.1.12.tar.gz
Algorithm Hash digest
SHA256 36fc21e786002add71f6933fce59b8ed46aba8b564ccf2c512b9603c87e1bf3a
MD5 1028a0ad55e1713c353f0a350a653321
BLAKE2b-256 eaa90962133923d3944a66f6efc451365ac22316dabecfe8a0d05f7e147158ca

See more details on using hashes here.

File details

Details for the file soulseal-0.1.12-py3-none-any.whl.

File metadata

  • Download URL: soulseal-0.1.12-py3-none-any.whl
  • Upload date:
  • Size: 36.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.0.0 CPython/3.11.7 Darwin/24.3.0

File hashes

Hashes for soulseal-0.1.12-py3-none-any.whl
Algorithm Hash digest
SHA256 db00691d9b83faebfdeb615d76b09e0d0404a730e1ab66be0c6e7ef737ffbaeb
MD5 ba39427eea21a84b0aedab1e2ff6e248
BLAKE2b-256 e0ed19e247c15b83380f20942b6eb054c8f6a4827750a1dd77c2b53dd7d577bd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page