В приложениях на Lit аутентификация часто реализуется через хранение состояния пользователя в глобальном или локальном хранилище. Основными подходами являются:
@property. Эти свойства автоматически отслеживают изменения
и обновляют DOM, что удобно для отображения интерфейса в зависимости от
состояния аутентификации.import { LitElement, html } from 'lit';
import { property } from 'lit/decorators.js';
class UserPanel extends LitElement {
@property({ type: Boolean })
loggedIn = false;
render() {
return html`
${this.loggedIn ? html`<p>Добро пожаловать, пользователь!</p>` : html`<p>Пожалуйста, войдите</p>`}
`;
}
}
customElements.define('user-panel', UserPanel);
import { LitElement, html } from 'lit';
import { store } from './store.js';
class AuthStatus extends LitElement {
connectedCallback() {
super.connectedCallback();
store.subscribe(() => this.requestUpdate());
}
render() {
const { user } = store.getState();
return html`${user ? html`<p>Привет, ${user.name}</p>` : html`<p>Вы не вошли</p>`}`;
}
}
customElements.define('auth-status', AuthStatus);
Аутентификация в современных веб-приложениях обычно строится на
использовании JWT или других токенов. В Lit токен можно хранить в
localStorage или sessionStorage, а при
создании компонента проверять его наличие и валидность.
class AuthCheck extends LitElement {
@property({ type: Boolean })
authenticated = false;
connectedCallback() {
super.connectedCallback();
const token = localStorage.getItem('authToken');
this.authenticated = !!token;
}
render() {
return html`
${this.authenticated ? html`<p>Доступ разрешён</p>` : html`<p>Доступ запрещён</p>`}
`;
}
}
customElements.define('auth-check', AuthCheck);
Для SPA на Lit часто используется комбинация с роутерами, такими как
@vaadin/router или lit-router. Защита
маршрутов строится через проверку состояния аутентификации перед
рендером компонента.
import { Router } from '@vaadin/router';
const router = new Router(document.querySelector('#outlet'));
router.setRoutes([
{ path: '/', component: 'home-page' },
{
path: '/dashboard',
component: 'dashboard-page',
action: async (context, commands) => {
const token = localStorage.getItem('authToken');
if (!token) return commands.redirect('/');
return undefined;
}
}
]);
Компоненты Lit могут предоставлять кнопки и формы для логина и логаута, обновляя реактивные свойства и хранилища. Важным моментом является корректная синхронизация состояния и локального хранилища.
class LoginForm extends LitElement {
@property({ type: Boolean })
loggedIn = false;
handleLogin() {
// эмуляция получения токена от сервера
const token = 'sample-jwt-token';
localStorage.setItem('authToken', token);
this.loggedIn = true;
}
handleLogout() {
localStorage.removeItem('authToken');
this.loggedIn = false;
}
render() {
return html`
${this.loggedIn
? html`<button @click=${this.handleLogout}>Выйти</button>`
: html`<button @click=${this.handleLogin}>Войти</button>`}
`;
}
}
customElements.define('login-form', LoginForm);
Если в приложении несколько компонентов зависят от состояния аутентификации, важно использовать централизованное хранилище или событие кастомного типа для уведомления всех компонентов:
// Dispatcher
export function authChanged(isLoggedIn) {
window.dispatchEvent(new CustomEvent('auth-changed', { detail: isLoggedIn }));
}
// Listener
class HeaderComponent extends LitElement {
@property({ type: Boolean }) loggedIn = false;
connectedCallback() {
super.connectedCallback();
window.addEventListener('auth-changed', e => this.loggedIn = e.detail);
}
render() {
return html`<p>${this.loggedIn ? 'Вы вошли' : 'Не вошли'}</p>`;
}
}
customElements.define('header-component', HeaderComponent);
Эти подходы обеспечивают гибкую, безопасную и реактивную архитектуру аутентификации в приложениях на Lit, позволяя управлять доступом к компонентам и маршрутам без излишней сложности.