Dart shelf - 中间件和处理程序执行顺序
Dart shelf - Middleware and handler execution order
我无法理解 Dart shelf 如何执行中间件和处理程序。从我阅读(并简要介绍)的所有文档中,如果您编写一个 returns null 的中间件,那么执行就会沿着管道进行。
否则如果中间件 returns 一个 Response,那么管道的执行就会停止,Response 返回给调用者。
我有一个带有简单管道的服务器:
var handler = const shelf.Pipeline()
.addMiddleware(shelf.logRequests())
//.addMiddleware(options)
.addMiddleware(auth)
.addHandler(Router.handle);
auth中间件检查3种情况:注册、登录和验证。
- 注册 -> 创建新用户和 returns Response.ok(令牌),或者如果不可能 Response.InternalServerError
- 登录 -> 刷新令牌和 returns Response.ok(令牌),或者如果不正确则响应(401)
- 验证 -> Returns 正常时为空(应继续沿着管道),或响应(403,禁止)
问题是,我无法停止中间件的执行。如果我成功登录,程序仍然会沿着管道向下并调用路由器。哪个当然没有 register 的路径和预期的 returns 404。
根据 shelf 文档,它应该在中间件 returns 响应时停止。我到底做错了什么?
这是auth中间件的代码供参考:
abstract class AuthProvider {
static JsonDecoder _decoder = const JsonDecoder();
static FutureOr<Response> handle(Request request) async {
print('Entering auth middleware');
if(request.url.toString() == 'login'){
print('into login from auth');
AuthProvider.auth(request);
}
else if(request.url.toString() == 'register'){
print('Into register from auth');
RegisterController.handle(request);
}
else {
print('Into verify from auth');
AuthProvider.verify(request);
}
}
static FutureOr<Response> auth(Request request) async {
print('Entering auth');
String sql;
var query = ExecQuery();
try {
dynamic data = jsonDecode(await request.readAsString()) as Map<String, dynamic>;
final user = data['email'].toString();
final hash = Hash.create(data['password'].toString());
sql =
'''SELECT COUNT(*) FROM public.user WHERE (email = '${user}' AND password = '${hash}')''';
await query.countSql(sql);
if (query.result.status && query.result.opResult[0][0] == 1) {
JwtClaim claim = JwtClaim(
subject: user,
issuer: 'Me',
audience: ['users'],
);
final token = issueJwtHS256(claim, config.secret);
sql = '''UPDATE public.user SET token = '${token}'
WHERE (email = '${user}' AND password = '${hash}')''';
await query.rawQuery(sql);
return Response.ok(token);
}
else{throw Exception();}
} catch (e) {
return Response(401, body: 'Incorrect username/password');
}
}
static FutureOr<Response> verify(Request request) async {
print('Entering verify');
try {
final token = request.headers['Authorization'].replaceAll('Bearer ', '');
print('Received token: ${token}');
final claim = verifyJwtHS256Signature(token, config.secret);
print('got the claim');
claim.validate(issuer: 'ACME Widgets Corp',
audience: 'homacenter');
print ('returning null in middleware');
return null;
} catch(e) {
print(e.toString());
return Response.forbidden('Authorization rejected');
}
}
}
我自己回答...在这方面浪费了几天之后,return 丢失了,这使得管道继续运行。问题已关闭。
abstract class AuthProvider {
static JsonDecoder _decoder = const JsonDecoder();
static FutureOr<Response> handle(Request request) async {
if(request.url.toString() == 'login'){
return AuthProvider.auth(request);
}
else if(request.url.toString() == 'register'){
return RegisterController.handle(request);
}
else {
return AuthProvider.verify(request);
}
}
我无法理解 Dart shelf 如何执行中间件和处理程序。从我阅读(并简要介绍)的所有文档中,如果您编写一个 returns null 的中间件,那么执行就会沿着管道进行。 否则如果中间件 returns 一个 Response,那么管道的执行就会停止,Response 返回给调用者。
我有一个带有简单管道的服务器:
var handler = const shelf.Pipeline()
.addMiddleware(shelf.logRequests())
//.addMiddleware(options)
.addMiddleware(auth)
.addHandler(Router.handle);
auth中间件检查3种情况:注册、登录和验证。
- 注册 -> 创建新用户和 returns Response.ok(令牌),或者如果不可能 Response.InternalServerError
- 登录 -> 刷新令牌和 returns Response.ok(令牌),或者如果不正确则响应(401)
- 验证 -> Returns 正常时为空(应继续沿着管道),或响应(403,禁止)
问题是,我无法停止中间件的执行。如果我成功登录,程序仍然会沿着管道向下并调用路由器。哪个当然没有 register 的路径和预期的 returns 404。
根据 shelf 文档,它应该在中间件 returns 响应时停止。我到底做错了什么?
这是auth中间件的代码供参考:
abstract class AuthProvider {
static JsonDecoder _decoder = const JsonDecoder();
static FutureOr<Response> handle(Request request) async {
print('Entering auth middleware');
if(request.url.toString() == 'login'){
print('into login from auth');
AuthProvider.auth(request);
}
else if(request.url.toString() == 'register'){
print('Into register from auth');
RegisterController.handle(request);
}
else {
print('Into verify from auth');
AuthProvider.verify(request);
}
}
static FutureOr<Response> auth(Request request) async {
print('Entering auth');
String sql;
var query = ExecQuery();
try {
dynamic data = jsonDecode(await request.readAsString()) as Map<String, dynamic>;
final user = data['email'].toString();
final hash = Hash.create(data['password'].toString());
sql =
'''SELECT COUNT(*) FROM public.user WHERE (email = '${user}' AND password = '${hash}')''';
await query.countSql(sql);
if (query.result.status && query.result.opResult[0][0] == 1) {
JwtClaim claim = JwtClaim(
subject: user,
issuer: 'Me',
audience: ['users'],
);
final token = issueJwtHS256(claim, config.secret);
sql = '''UPDATE public.user SET token = '${token}'
WHERE (email = '${user}' AND password = '${hash}')''';
await query.rawQuery(sql);
return Response.ok(token);
}
else{throw Exception();}
} catch (e) {
return Response(401, body: 'Incorrect username/password');
}
}
static FutureOr<Response> verify(Request request) async {
print('Entering verify');
try {
final token = request.headers['Authorization'].replaceAll('Bearer ', '');
print('Received token: ${token}');
final claim = verifyJwtHS256Signature(token, config.secret);
print('got the claim');
claim.validate(issuer: 'ACME Widgets Corp',
audience: 'homacenter');
print ('returning null in middleware');
return null;
} catch(e) {
print(e.toString());
return Response.forbidden('Authorization rejected');
}
}
}
我自己回答...在这方面浪费了几天之后,return 丢失了,这使得管道继续运行。问题已关闭。
abstract class AuthProvider {
static JsonDecoder _decoder = const JsonDecoder();
static FutureOr<Response> handle(Request request) async {
if(request.url.toString() == 'login'){
return AuthProvider.auth(request);
}
else if(request.url.toString() == 'register'){
return RegisterController.handle(request);
}
else {
return AuthProvider.verify(request);
}
}