Auth Controller

AuthController 是一个抽象类,为 Finch 路由提供访问控制。您创建一个子类、实现抽象方法,并将实例传递给要保护的每个 FinchRouteauth 选项。

抽象方法

方法 签名 描述
auth Future<bool> auth(Request rq, List<String> permissions) 返回 true 表示允许,返回 false 表示拒绝。permissions 来自 FinchRoute.permissions
reject Future<String> reject(Request rq, List<String> permissions) auth 拒绝时发送的响应(重定向、错误页面、JSON)

完整示例

import 'package:finch/finch_route.dart';

class AppAuthController extends AuthController {
  @override
  Future<bool> auth(Request rq, List<String> permissions) async {
    // 从 header 或 session 读取 token
    var token = rq.headers['authorization']?.first ?? '';

    if (token.isEmpty) return false;

    // 在数据库或存储中验证 token
    var user = await UserModel().findByToken(token: token);
    if (user == null) return false;

    // 如果指定了权限,检查权限
    if (permissions.isNotEmpty) {
      return permissions.every((p) => user.roles.contains(p));
    }
    return true;
  }

  @override
  Future<String> reject(Request rq, List<String> permissions) async {
    // 对于 API 请求
    if (rq.isJson) {
      return rq.renderData(
        data: {'error': 'Unauthorized'},
        statusCode: 401,
      );
    }
    // 对于浏览器请求
    return rq.redirect(url: '/login');
  }
}

附加到路由

final authController = AppAuthController();

Future<List<FinchRoute>> getWebRoute(Request rq) async {
  return [
    // 保护单个路由
    FinchRoute(
      key: 'admin.panel',
      path: 'admin/panel',
      auth: authController,
      permissions: ['admin'],
      index: adminController.panel,
    ),

    // 保护父路由及其所有子路由
    FinchRoute(
      key: 'dashboard',
      path: 'dashboard',
      auth: authController,
      children: [
        FinchRoute(
          key: 'dashboard.home',
          path: '',
          index: dashboardController.home,
        ),
        FinchRoute(
          key: 'dashboard.settings',
          path: 'settings',
          index: dashboardController.settings,
        ),
      ],
    ),
  ];
}

请求流程

传入请求
    → 如果设置了 auth:调用 AuthController.auth()
        → false:发送 AuthController.reject()
        → true:执行控制器 index 方法

Authorization 头部

标准的 Authorization 头部不由 Finch 自动解析。从 rq.headers 手动读取它:

var authHeader = rq.headers['authorization']?.first ?? '';
// 通常格式:'Bearer <token>'
var token = authHeader.replaceFirst('Bearer ', '');