Маршрутизация и авторизация во фронтенд-приложениях на Knockout.js обычно реализуются без «из коробки» решений. Фреймворк предоставляет реактивную модель данных и биндинги, а архитектура защищённых маршрутов строится поверх него — с использованием сторонних библиотек или собственной логики.
Knockout.js не включает встроенный роутер, поэтому на практике применяются:
location.hash или
history.pushStateТиповой маршрут связывает URL с состоянием приложения и активной моделью представления.
function AppViewModel() {
this.currentPage = ko.observable('login');
}
var app = new AppViewModel();
ko.applyBindings(app);
function router() {
var hash = location.hash.replace('#', '');
app.currentPage(hash || 'login');
}
window.addEventListener('hashchange', router);
router();
Защищённый маршрут — это состояние приложения, доступ к которому разрешён только аутентифицированному пользователю. Проверка выполняется до активации представления или во время смены маршрута.
Ключевые требования:
Состояние авторизации обычно хранится в корневой модели приложения.
function AuthService() {
this.isAuthenticated = ko.observable(false);
this.user = ko.observable(null);
}
var auth = new AuthService();
После успешного входа:
auth.isAuthenticated(true);
auth.user({ id: 1, role: 'admin' });
Это состояние реактивно и автоматически обновляет интерфейс.
Каждому маршруту сопоставляется метаинформация:
var routes = {
login: { secure: false },
dashboard: { secure: true },
profile: { secure: true },
admin: { secure: true, role: 'admin' }
};
При изменении маршрута выполняется проверка:
function router() {
var hash = location.hash.replace('#', '') || 'login';
var route = routes[hash];
if (route.secure && !auth.isAuthenticated()) {
location.hash = 'login';
return;
}
if (route.role && auth.user()?.role !== route.role) {
location.hash = 'dashboard';
return;
}
app.currentPage(hash);
}
Представления можно переключать с помощью if или
visible.
<div data-bind="if: currentPage() === 'dashboard'">
<!-- ko component: 'dashboard-page' --><!-- /ko -->
</div>
<div data-bind="if: currentPage() === 'login'">
<!-- ko component: 'login-page' --><!-- /ko -->
</div>
Реактивность Knockout.js гарантирует, что неавторизованный пользователь физически не увидит защищённый контент.
Для сложных сценариев используется ролевая модель:
this.hasRole = function(role) {
return auth.isAuthenticated() && auth.user()?.role === role;
};
В шаблонах:
<button data-bind="visible: hasRole('admin')">
Панель администратора
</button>
Это исключает дублирование проверок и повышает читаемость.
Чтобы пользователь не терял сессию при обновлении страницы, данные авторизации сохраняются:
localStoragesessionStorageauth.isAuthenticated.subscribe(function(value) {
localStorage.setItem('auth', value);
});
При инициализации:
auth.isAuthenticated(
localStorage.getItem('auth') === 'true'
);
При использовании JWT или аналогичных токенов необходимо валидировать их при загрузке:
var token = localStorage.getItem('token');
if (token) {
fetch('/api/validate', {
headers: { Authorization: 'Bearer ' + token }
})
.then(r => r.ok ? r.json() : Promise.reject())
.then(user => {
auth.isAuthenticated(true);
auth.user(user);
})
.catch(() => {
auth.isAuthenticated(false);
auth.user(null);
});
}
Маршрутизация запускается после этой проверки.
Компоненты Knockout.js также могут проверять авторизацию при инициализации:
ko.components.register('dashboard-page', {
viewModel: function() {
if (!auth.isAuthenticated()) {
location.hash = 'login';
}
},
template: '...'
});
Это дополнительный уровень защиты при динамической загрузке.
Для масштабных приложений логика проверки выносится в единый guard:
function canActivate(route) {
if (route.secure && !auth.isAuthenticated()) {
return false;
}
if (route.role && auth.user()?.role !== route.role) {
return false;
}
return true;
}
Использование:
if (!canActivate(route)) {
location.hash = 'login';
return;
}
Клиентская авторизация:
Все защищённые данные и действия должны проверяться на сервере. Knockout.js отвечает только за управление состоянием и отображением.
Knockout.js хорошо подходит для построения прозрачной и управляемой модели защищённых маршрутов за счёт наблюдаемых значений и предсказуемого потока данных.