Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
252 views
in Technique[技术] by (71.8m points)

Dart shelf - Middleware and handler execution order

I'm lost trying to understand how Dart shelf executes the middleware and handlers. From all the documentation I have read (and briefing it up) if you write a Middleware that returns null, then the execution goes down the pipeline. Otherwise if the middleware returns a Response, then the execution down the pipeline is stopped, and the Response is returned to the caller.

I have a server with a simple pipeline like this:

    var handler = const shelf.Pipeline()
    .addMiddleware(shelf.logRequests())
//.addMiddleware(options)
    .addMiddleware(auth)
    .addHandler(Router.handle);

The auth middleware checks 3 cases: Register, Login and Verify.

  • Register -> Creates new user and returns Response.ok(token), or if nor possible Response.InternalServerError
  • Login -> Refreshes the token and returns Response.ok(token), or if not correct Response(401)
  • Verify -> Returns null when ok(should continue down the pipeline), or Response(403, forbidden)

The problem is, that I cannot stop the execution of the middlewares. If I make a successful login, still the program goes down the pipeline and calls the Router. Which of course doesn't have the path for register and returns 404 as it is expected to do.

According to shelf documentation, it is supposed to stop when a middleware returns a response. What the hell am I doing wrong?

This is the code of the auth Middleware for reference:

    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');
        }
      }
    }
question from:https://stackoverflow.com/questions/65901123/dart-shelf-middleware-and-handler-execution-order

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I reply myself... after losing days in this, a return was missing, that made the pipeline keep going. Issue closed.

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);
    }
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...