我创建了一个中间件控制器,负责身份验证。控制器将链接在资源控制器的前面。我认为这是正确的方法吗?
在handle 方法中,我正在执行一个数据库查询,它需要连接信息。但是,当我尝试通过构造函数传递数据时,它告诉我不允许设置器。
将带有连接信息的 Map 从 channel.dart 传递到中间件控制器的最佳方法是什么(请参阅 dbConnectionDetails)?
通道.dart
@override
Future prepare() async {
logger.onRecord.listen((rec) => print("$rec ${rec.error ?? ""} ${rec.stackTrace ?? ""}"));
dbConnectionDetails = ConnectionSettings (
user: "mydbuser",
password: "mydbpass",
host: "localhost",
port: 3306
);
}
@override
Controller get entryPoint {
final router = Router();
router
.route("/api/user/query/complex")
.link(() => AuthMiddleware())
.link(() => UserComplexQueryController(dbConnectionDetails));
}
在上面的示例中,我可以将 dbConnectionDetails 传递给 UserComplexQueryController 的构造函数,以便我可以将其用于数据库连接。
但是,如果我将 dbConnectionDetails 传递给 AuthMiddleWare 的构造函数,则会出现以下错误:
ArgumentError(无效的参数:无效的控制器“AuthMiddleware”。控制器不能有设置器,所有字段都必须标记为最终字段,或者它必须实现“可回收”。)
就我而言,AuthMiddleWare 正在获取在 URL 中解析的令牌,并将检查令牌在数据库中是否有效。如您所见,我发现除了直接在 AuthMiddleware isValid 函数中添加 dbConnectionDetails 之外别无他法。但我更愿意,如果我可以从 channel.dart 传递它。
class AuthMiddleware extends Controller {
// This does not work, as setters not allowed
//AuthMiddleware(this.dbConnectionDetails);
//
//ConnectionSettings dbConnectionDetails
@override
Future<RequestOrResponse> handle(Request request) async {
if (await isValid(request)) {
return request;
}
return Response.unauthorized();
}
Future<bool> isValid(Request request) async {
final String token = request.raw.requestedUri.queryParameters["token"];
final int timestamp = (DateTime.now().toUtc().millisecondsSinceEpoch / 1000).round();
ConnectionSettings dbConnectionDetails = ConnectionSettings (
user: "myuser",
password: "mypass",
host: "localhost",
port: 3306
);
AuthTokenDao authTokenDao = new AuthTokenDao(dbConnectionDetails);
if(await authTokenDao.validateToken(token, timestamp)) {
return true;
}
return false;
}
}
是的,你没看错。我正在连接到 MySQL 数据库:)