#!/usr/bin/env python
# coding: utf-8
"""
认证授权模块
提供完整的用户认证和授权解决方案:
- JWT Token 认证
- OAuth2 社交登录
- 用户注册/登录
- 密码加密
- 权限控制
- Token 刷新
- 认证中间件
使用示例::
from litefs.auth import Auth, login_required, role_required
auth = Auth(app, secret_key='your-secret-key')
@route('/protected')
@login_required
def protected(request):
return {'user': request.user.username}
@route('/admin')
@role_required('admin')
def admin_only(request):
return {'message': 'Admin access'}
OAuth2 示例::
from litefs.auth import OAuth2
oauth = OAuth2(app)
oauth.register(
name='github',
client_id='your-client-id',
client_secret='your-client-secret',
redirect_uri='http://localhost:8080/auth/github/callback'
)
@route('/login/github')
def github_login(request):
return oauth.authorize_redirect(request, 'github')
@route('/auth/github/callback')
def github_callback(request):
user_info = oauth.authorize_user(request, 'github')
return {'user': user_info.to_dict()}
"""
from .jwt import JWTManager, create_token, decode_token
from .password import hash_password, verify_password
from .middleware import AuthMiddleware, login_required, role_required
from .decorators import permission_required, current_user
from .models import (
User,
Role,
Permission,
init_default_roles_and_permissions,
BaseUserStore,
MemoryUserStore,
get_user_store,
set_user_store,
)
from .oauth2 import OAuth2, OAuth2State, create_oauth2_blueprint
from .providers import (
OAuth2Provider,
OAuth2UserInfo,
GitHubProvider,
GoogleProvider,
WeChatProvider,
WeComProvider,
get_provider,
)
__all__ = [
'Auth',
'JWTManager',
'create_token',
'decode_token',
'hash_password',
'verify_password',
'AuthMiddleware',
'login_required',
'role_required',
'permission_required',
'current_user',
'User',
'Role',
'Permission',
'BaseUserStore',
'MemoryUserStore',
'get_user_store',
'set_user_store',
'init_default_roles_and_permissions',
'OAuth2',
'OAuth2State',
'OAuth2Provider',
'OAuth2UserInfo',
'GitHubProvider',
'GoogleProvider',
'WeChatProvider',
'WeComProvider',
'get_provider',
'create_oauth2_blueprint',
]
[文档]
class Auth:
"""
认证授权管理器
提供完整的用户认证和授权功能。
"""
def __init__(
self,
app=None,
secret_key: str = None,
algorithm: str = 'HS256',
access_token_expires: int = 3600,
refresh_token_expires: int = 604800,
token_location: str = 'header',
token_name: str = 'Authorization',
token_prefix: str = 'Bearer',
):
"""
初始化认证管理器
Args:
app: Litefs 应用实例
secret_key: JWT 密钥
algorithm: JWT 算法
access_token_expires: Access Token 过期时间(秒)
refresh_token_expires: Refresh Token 过期时间(秒)
token_location: Token 位置 ('header', 'cookie', 'query')
token_name: Token 名称
token_prefix: Token 前缀
"""
self.secret_key = secret_key or 'change-me-in-production'
self.algorithm = algorithm
self.access_token_expires = access_token_expires
self.refresh_token_expires = refresh_token_expires
self.token_location = token_location
self.token_name = token_name
self.token_prefix = token_prefix
self._jwt = JWTManager(
secret_key=self.secret_key,
algorithm=self.algorithm,
access_token_expires=self.access_token_expires,
refresh_token_expires=self.refresh_token_expires,
)
self._middleware = AuthMiddleware(
jwt_manager=self._jwt,
token_location=token_location,
token_name=token_name,
token_prefix=token_prefix,
)
if app:
self.init_app(app)
[文档]
def init_app(self, app):
"""
初始化应用
Args:
app: Litefs 应用实例
"""
app.add_middleware(self._middleware.__class__, jwt_manager=self._jwt)
app.add_post('/auth/login', self.login_handler, name='auth_login')
app.add_post('/auth/register', self.register_handler, name='auth_register')
app.add_post('/auth/refresh', self.refresh_handler, name='auth_refresh')
app.add_post('/auth/logout', self.logout_handler, name='auth_logout')
[文档]
def login_handler(self, request):
"""登录处理"""
data = request.json or {}
username = data.get('username')
password = data.get('password')
if not username or not password:
return {'error': '用户名和密码不能为空'}, 400
store = get_user_store()
user = store.get_by_username(username)
if not user or not verify_password(password, user.password_hash):
return {'error': '用户名或密码错误'}, 401
access_token = self._jwt.create_access_token({'sub': user.id, 'username': user.username})
refresh_token = self._jwt.create_refresh_token({'sub': user.id})
return {
'access_token': access_token,
'refresh_token': refresh_token,
'token_type': 'Bearer',
'expires_in': self.access_token_expires,
}
[文档]
def register_handler(self, request):
"""注册处理"""
data = request.json or {}
username = data.get('username')
password = data.get('password')
email = data.get('email')
if not username or not password:
return {'error': '用户名和密码不能为空'}, 400
store = get_user_store()
if store.get_by_username(username):
return {'error': '用户名已存在'}, 400
password_hash = hash_password(password)
user = store.create(
username=username,
password_hash=password_hash,
email=email,
)
return {'message': '注册成功', 'user_id': user.id}, 201
[文档]
def refresh_handler(self, request):
"""Token 刷新处理"""
data = request.json or {}
refresh_token = data.get('refresh_token')
if not refresh_token:
return {'error': 'Refresh Token 不能为空'}, 400
payload = self._jwt.decode_token(refresh_token)
if not payload or payload.get('type') != 'refresh':
return {'error': '无效的 Refresh Token'}, 401
user_id = payload.get('sub')
store = get_user_store()
user = store.get_by_id(user_id)
if not user:
return {'error': '用户不存在'}, 401
access_token = self._jwt.create_access_token({'sub': user.id, 'username': user.username})
return {
'access_token': access_token,
'token_type': 'Bearer',
'expires_in': self.access_token_expires,
}
[文档]
def logout_handler(self, request):
"""登出处理"""
return {'message': '登出成功'}
[文档]
def create_user(self, username: str, password: str, **kwargs):
"""
创建用户
Args:
username: 用户名
password: 密码
**kwargs: 其他属性(email, roles 等)
Returns:
User 实例
"""
password_hash = hash_password(password)
return get_user_store().create(username=username, password_hash=password_hash, **kwargs)
[文档]
def authenticate(self, username: str, password: str):
"""
验证用户
Args:
username: 用户名
password: 密码
Returns:
User 实例或 None
"""
user = get_user_store().get_by_username(username)
if user and verify_password(password, user.password_hash):
return user
return None