Защита маршрутов в Dart Webapp

Я создаю веб-приложение Dart/Aqueduct, в котором мне нужно иметь возможность ограничивать доступ к определенным маршрутам. Я использую авторизаторы Aqueducts при выполнении HTTP-запроса, но меня немного беспокоит контроль доступа пользователей в самом приложении dart.

При маршрутизации на разные страницы в веб-приложении я использую маршрутизацию Dart, то есть:

 const Route(path: '/heroes', name: 'Heroes', component: HeroesComponent)

Это позволяет мне использовать другой шаблон и компонент по новому URL-адресу, однако HTTP-запрос не выполняется. Есть ли способ эффективно реализовать пользовательские области, когда пользователь находится в приложении?

Я думал проверить токен доступа при инициализации маршрутизируемых компонентов и не отображать информацию, если пользователь не аутентифицирован, но не будет ли у пользователя доступ к содержимому этой страницы, поскольку веб-приложения dart входят в предварительно скомпилированный пакет JS?


person Arthur Daniel    schedule 13.07.2017    source источник
comment
Вы можете использовать аннотацию @CanActivate(). Это немного громоздко, потому что использование DI в настоящее время требует уродливого взлома. Но это не так уж сложно. Вы также можете добавить проверку компонента, если пользователь вошел в систему, а если нет, просто вызовите router.navigate('/login')   -  person Günter Zöchbauer    schedule 13.07.2017


Ответы (2)


Простите меня, если я неправильно понял ваш вопрос или если вы уже знаете большую часть этого, но похоже, что вы спрашиваете о различии между данными, отображаемыми приложением, и самим приложением. Или, в более общем смысле, разница между одностраничным приложением и страницей, отображаемой на стороне сервера.

В приложении рендеринга на стороне сервера каждая навигация загружает новый URL-адрес с сервера (или из кэша). Сервер использует информацию об авторизации из запроса, чтобы получить соответствующие данные, вставить их в шаблон HTML-страницы, а затем вернуть эту страницу. По мнению клиента, данные, отображаемые на странице, и сама страница представляют собой единое целое. Если данные не могут быть извлечены, возвращается другая страница, указывающая, что у пользователя нет доступа.

В одностраничном приложении каждая возможная «страница», на которую вы можете перейти, загружается один раз, и все они лишены каких-либо фактических данных. Вместо этого эти страницы являются контейнером для данных. Поведение этих страниц делает запросы API к серверу для отображения данных.

Само приложение не защищено — любой может перейти к нему или любой из его страниц. Однако данные защищены. Если у пользователя нет доступа к данным, запрошенным вызовом API, возвращается код состояния 401 с телом ошибки JSON.

Следовательно, должно быть различие между маршрутами на стороне клиента и на стороне сервера. Вы уже заметили, что маршруты на стороне клиента на самом деле не делают HTTP-запрос — это сделано намеренно.

Если вы обслуживаете приложение и API из одного и того же приложения, рекомендуется ставить перед всеми вашими маршрутами API что-то вроде /api. Например, маршрут на стороне клиента — /heroes, а маршрут на стороне сервера — /api/heroes. Это также позволяет мобильному приложению (или любому другому небраузерному приложению) использовать ваш API; им не нужен HTML, потому что у них есть собственное поведение рендеринга.

Как сказал Гюнтер, если есть страница, которая бесполезна без доступа к данным API, верните их на страницу входа. Существует два сценария, когда у вас нет доступа к данным API: у вас вообще нет токена доступа и срок действия вашего токена доступа истек.

Сделайте запрос API при переходе на клиентский маршрут /heroes. Если у вас нет токена доступа, перенаправьте их на страницу входа. Если запрос выдаст ошибку 401, верните их обратно на страницу входа. Если вы получите обратно 200, то действуйте как обычно.

Одно место, где маршрутизация на стороне клиента мешает, — это попытка ввести URL-адрес маршрута на стороне клиента в браузере (в отличие от программного перехода к нему). Существуют разные стратегии обхода этого, вот одна из них: https://github.com/stablekernel/aqueduct/issues/274.

person Joe Conway    schedule 14.07.2017
comment
Спасибо за ваши отличные ответы, Джо. Я попытаюсь использовать предложение Гюнтера и проверить ответ 401 при получении любых моих данных, чтобы убедиться, что пользователь аутентифицирован. - person Arthur Daniel; 17.07.2017

Рассмотрите возможность создания двух приложений: одно, которое просто содержит страницу входа/регистрации, а другое — с вашими защищенными функциями.

Вам нужно будет написать код на сервере, чтобы только авторизованные пользователи могли видеть защищенное приложение. В противном случае вы можете выдать ошибку 403 или перенаправить гостей на страницу входа.

Надеюсь это поможет.

person Tobe O    schedule 13.07.2017