aqueduct经验

注册数据库控制器
最后,您需要将数据库控制器注册到应用程序中:

import 'controller/user_controller.dart';

class YourAppChannel extends ApplicationChannel {
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final persistentStore = PostgreSQLPersistentStore(
      'username', 'password', 'localhost', 5432, 'your_database_name');
    context = ManagedContext(dataModel, persistentStore);
  }

  @override
  Controller get entryPoint {
    final router = Router();

    router
      .route('/users/[:id]')
      .link(() => UserController(context));

    return router;
  }
}

创建数据库模型

注册数据库控制器
import 'controller/user_controller.dart';

class YourAppChannel extends ApplicationChannel {
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final persistentStore = PostgreSQLPersistentStore(
      'username', 'password', 'localhost', 5432, 'your_database_name');
    context = ManagedContext(dataModel, persistentStore);
  }

  @override
  Controller get entryPoint {
    final router = Router();

    router
      .route('/users/[:id]')
      .link(() => UserController(context));

    return router;
  }
}
创建数据库模型
import 'package:aqueduct/aqueduct.dart';

class User extends ManagedObject<_User> implements _User {}

class _User {
  @primaryKey
  int id;

  @Column(unique: true)
  String username;
  
  @Column()
  String email;
}
创建数据库控制器
import 'package:aqueduct/aqueduct.dart';
import 'package:yourapp/model/user.dart';

class UserController extends ResourceController {
  UserController(this.context);

  final ManagedContext context;

  @Operation.post()
  Future<Response> createUser(@Bind.body() User user) async {
    final query = Query<User>(context)..values = user;
    final insertedUser = await query.insert();
    return Response.ok(insertedUser);
  }

  @Operation.get()
  Future<Response> getAllUsers() async {
    final query = Query<User>(context);
    final users = await query.fetch();
    return Response.ok(users);
  }

  @Operation.put('id')
  Future<Response> updateUser(@Bind.path('id') int id, @Bind.body() User user) async {
    final query = Query<User>(context)
      ..where((u) => u.id).equalTo(id)
      ..values = user;
    final updatedUser = await query.updateOne();
    return Response.ok(updatedUser);
  }

  @Operation.delete('id')
  Future<Response> deleteUser(@Bind.path('id') int id) async {
    final query = Query<User>(context)..where((u) => u.id).equalTo(id);
    final deletedUser = await query.delete();
    return Response.ok(deletedUser);
  }
}
创建一个名为 auth_controller.dart 的控制器文件,并在其中实现用户验证的逻辑
import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct/managed_auth.dart';

class AuthController extends ResourceController {
  AuthServer authServer;

  AuthController(this.authServer);

  @Operation.post('username', 'password')
  Future<Response> login(@Bind.path('username') String username, @Bind.path('password') String password) async {
    final query = Query<User>(context)
      ..where((u) => u.username).equalTo(username);
    final user = await query.fetchOne();

    if (user == null || !user.matchesPassword(password)) {
      return Response.unauthorized();
    }

    final token = await authServer.authenticateForUser(user);
    return Response.ok(token);
  }
}
在应用程序的主文件中,将创建的 AuthController 注册到路由中
import 'auth_controller.dart';

class MyAppChannel extends ApplicationChannel {
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final persistentStore = PostgreSQLPersistentStore(/* 数据库连接配置 */);
    context = ManagedContext(dataModel, persistentStore);
  }

  @override
  Controller get entryPoint {
    final authStorage = ManagedAuthDelegate<User>(context);
    final authServer = AuthServer(authStorage);

    return Router()
      ..route('/auth/token').link(() => AuthController(authServer));
  }
}
创建一个名为 auth_middleware.dart 的中间件文件,并在其中实现权限验证逻辑
import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct/managed_auth.dart';

class AuthMiddleware extends Controller {
  AuthServer authServer;

  AuthMiddleware(this.authServer);

  @override
  Future<RequestOrResponse> handle(Request request) async {
    // 从请求中获取 token
    final token = request.raw.headers.value('authorization');

    if (token == null) {
      return Response.unauthorized();
    }

    final validatedToken = await authServer.validateToken(token);

    if (validatedToken == null) {
      return Response.unauthorized();
    }

    // 在请求上下文中存储验证通过的用户信息
    request.attachments['user'] = validatedToken.resourceOwnerIdentifier;

    return request;
  }
}
在应用程序的主文件中,将创建的 AuthMiddleware 注册到路由中作为全局中间件
import 'auth_middleware.dart';

class MyAppChannel extends ApplicationChannel {
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final persistentStore = PostgreSQLPersistentStore(/* 数据库连接配置 */);
    context = ManagedContext(dataModel, persistentStore);
  }

  @override
  Controller get entryPoint {
    final authStorage = ManagedAuthDelegate<User>(context);
    final authServer = AuthServer(authStorage);

    final router = Router()
      ..route('/auth/token').link(() => AuthController(authServer))
      // 将 AuthMiddleware 注册为全局中间件
      ..link(() => AuthMiddleware(authServer))
      // 其他路由定义
      ;

    return router;
  }
}

 











代码示例
import 'aqueduct/aqueduct.dart';

class MyAppChannel extends ApplicationChannel {
  @override
  Future prepare() async {
    // 初始化数据库连接等操作
  }

  @override
  Controller get entryPoint {
    final router = Router();

    // 1. 网站端口为6081
    router.route('/').linkFunction((request) async {
      return Response.ok('Hello, world!')
        ..contentType = ContentType.html;
    });

    // 2. 使用orm接口进行数据增删查改访问,过程要求通过非ID字段进行查找数据
    router.route('/items').link(() => ItemsController(context));

    // 3. 使用token进行权限验证
    router.route('/secure').link(() => SecureController());

    // 4. 接收前端上传的图片文件并保存
    router.route('/upload').link(() => UploadController());

    return router;
  }
}

class ItemsController extends ResourceController {
  final ManagedContext context;

  ItemsController(this.context);

  @Operation.get()
  Future<Response> getItems(@Bind.query('name') String name) async {
    final query = Query<Item>(context)
      ..where((item) => item.name).equalTo(name);

    final items = await query.fetch();

    // 5. 将数据库返回的false和true转化为可授权和不可授权后返回前端
    final transformedItems = items.map((item) {
      return {
        'name': item.name,
        'authorized': item.authorized ? '可授权' : '不可授权'
      };
    }).toList();

    // 6. 返回前端的数据中带有前端自己的访问ip
    final clientIP = request.connectionInfo.remoteAddress.address;

    return Response.ok(transformedItems)
      ..contentType = ContentType.json
      ..write(clientIP);
  }
}

class SecureController extends ResourceController {
  @Operation.get()
  Future<Response> getSecureData() async {
    // 验证token逻辑
    if (/* token验证通过 */) {
      return Response.ok('Secure Data');
    } else {
      return Response.forbidden();
    }
  }
}

class UploadController extends ResourceController {
  @Operation.post()
  Future<Response> uploadFile(@Bind.multipart('file') FileUpload file) async {
    // 保存上传的文件逻辑
    final savedFilePath = /* 保存文件的路径 */;
    return Response.ok('File uploaded: $savedFilePath');
  }
}

class Item extends ManagedObject<_Item> implements _Item {}

class _Item {
  @primaryKey
  int id;

  @Column(unique: true)
  String name;

  @Column(defaultValue: 'false')
  bool authorized;
}

Future main() async {
  final app = Application<MyAppChannel>()
    ..options.configurationFilePath = 'config.yaml';

  await app.start(numberOfInstances: 3);
}

 

posted @ 2023-12-25 11:00  pearlcity  阅读(2)  评论(0编辑  收藏  举报