Как проверить установленный сеанс с использованием библиотеки shelf_auth?

Я пытался написать простой сервер, который принимает учетные данные имени пользователя / пароля, проверяет их, а затем создает токен JWT для клиента, который они затем используют для получения доступа к определенным маршрутам. Я могу сделать все, вплоть до получения и проверки JWT клиента на стороне сервера.

void main() {
//use Jwt based sessions and create the secret using a UUID
JwtSessionHandler sessionHandler = 
    new JwtSessionHandler('ffl_sales_server', new Uuid().v4(), 
    auth.lookupByUsername);

  //allow http for testing with curl, do not use in production
  bool allowHttp = true;

  final Map<String, String> headers = 
    {'Access-Control-Allow-Origin': 'http://192.168.100.83:3030',
     "Access-Control-Expose-Headers": "Authorization",
     "Access-Control-Allow-Credentials" : "true",
     "Access-Control-Allow-Headers" : "Authorization"};

  //fix the cors headers 
  Response options(Request request) => (request.method == 'OPTIONS') ?
      new Response.ok(null, headers: headers) : null;
  Response cors(Response response) => 
      response.change(headers: headers);
  Middleware fixCors = createMiddleware(requestHandler: options, 
      responseHandler: cors);

  // authentication middleware for a login handler (post)
  Middleware loginMiddleware = authenticate(
      [new UsernamePasswordAuthenticator(lookupByUsernamePassword)],
      sessionHandler: sessionHandler, allowHttp: allowHttp, 
      allowAnonymousAccess: false);

  // authentication middleware for routes other than login that 
  // require a logged in user
  // here we are relying solely on users with a session established  
  // via the login route
  Middleware defaultAuthMiddleware = authenticate(
      [],sessionHandler: sessionHandler, allowHttp: true, 
      allowAnonymousAccess: false);

  Router rootRouter = router(handlerAdapter: handlerAdapter()); 

  //the route where the login credentials are posted
  rootRouter.post('/login', (Request request) => new Response.ok('SUCCESS'), middleware: loginMiddleware);

  //the routes which require an authenticated user
  rootRouter.child('/authenticated', 
      middleware: defaultAuthMiddleware)
    ..add('/users', ALL_METHODS, new Users(_connection).handle)
    ..add('/stores', ALL_METHODS, new Stores(_connection).handle)
    ..add('/departments', ALL_METHODS, new Departments(_connection).handle)
    ..add('/invoices', ALL_METHODS, new Invoices(_connection).handle)
    ..add('/reports', ALL_METHODS, new Reports(_connection).handle)
    ..add('/imports', ALL_METHODS, new Imports(_connection).handle)
    ..add('/vendors', ALL_METHODS, new Vendors(_connection).handle)
    ..get('/foo', (Request request) => 
         new Response.ok("Doing foo as ${loggedInUsername(request)}\n"));

  printRoutes(rootRouter);

  Handler handler = const Pipeline()
      .addMiddleware(fixCors)
      .addMiddleware(logRequests())
      .addMiddleware(exceptionResponse())
      .addHandler(rootRouter.handler);

  shelf_io.serve(handler, '127.0.0.1', '8080').then((server){
    print('Serving as http://${server.address.host}:${server.port}');
  });
}

Я знаю, что, возможно, мне не хватает чего-то простого, но, похоже, у меня должен быть какой-то обработчик в первом параметре функции authenticate(), которая создает defaultAuthMiddleware. Что мне не хватает?

2 ответа

Решение

Похоже, проблема была в моем классе Auth. Функция lookupByUsername просто не находила аутентифицированного пользователя, потому что функция lookupByUsernamePassword сохраняла его в области функции вместо области класса из-за недосмотра с моей стороны.

Спасибо за помощь!

Я думаю, что вам нужно передать sessionMiddleware на другие маршруты, такие как

 ..add('/invoices', ALL_METHODS, new Invoices(_connection).handle, 
     middleware: defaultAuthMiddleware)

Может быть, есть лучший способ, но это основное различие, которое я нашел в моей настройке, которая работает нормально.

Другие вопросы по тегам