Аутентификация является процессом подтверждения подлинности пользователя и чаще всего реализуется через формы входа с использованием логина и пароля. В контексте Polymer аутентификация строится на компонентах веб-приложений и взаимодействии с серверными API через AJAX или Fetch.
Для начала необходимо создать пользовательский элемент формы входа:
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
class LoginForm extends PolymerElement {
static get properties() {
return {
username: { type: String, value: '' },
password: { type: String, value: '' },
errorMessage: { type: String, value: '' }
};
}
static get template() {
return html`
<style>
form { display: flex; flex-direction: column; width: 300px; }
input { margin-bottom: 10px; padding: 8px; }
.error { color: red; }
</style>
<form on-submit="handleLogin">
<input type="text" placeholder="Имя пользователя" value="{{username::input}}">
<input type="password" placeholder="Пароль" value="{{password::input}}">
<button type="submit">Войти</button>
<div class="error">[[errorMessage]]</div>
</form>
`;
}
handleLogin(event) {
event.preventDefault();
fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: this.username, password: this.password })
})
.then(response => response.json())
.then(data => {
if (data.success) {
sessionStorage.setItem('authToken', data.token);
this.errorMessage = '';
this.dispatchEvent(new CustomEvent('login-success', { detail: data }));
} else {
this.errorMessage = 'Неверное имя пользователя или пароль';
}
})
.catch(() => {
this.errorMessage = 'Ошибка сервера. Попробуйте позже.';
});
}
}
customElements.define('login-form', LoginForm);
Ключевые моменты:
{{}} позволяет
автоматически синхронизировать данные формы с полями класса.fetch выполняет POST-запрос к серверу и
обрабатывает ответ JSON.sessionStorage
обеспечивает доступ к нему в рамках текущей сессии.После аутентификации важно ограничивать доступ к защищённым ресурсам. В Polymer это реализуется через проверку токена перед отображением определённых компонентов.
Пример компонента с авторизацией:
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
class ProtectedPage extends PolymerElement {
static get properties() {
return {
authToken: { type: String, value: '' },
isAuthorized: { type: Boolean, value: false }
};
}
connectedCallback() {
super.connectedCallback();
this.authToken = sessionStorage.getItem('authToken') || '';
this.isAuthorized = !!this.authToken;
if (!this.isAuthorized) {
this.dispatchEvent(new CustomEvent('redirect-login'));
}
}
static get template() {
return html`
<template is="dom-if" if="[[isAuthorized]]">
<div>Добро пожаловать на защищённую страницу</div>
</template>
<template is="dom-if" if="[[!isAuthorized]]">
<div>Доступ запрещён. Перенаправление на страницу входа...</div>
</template>
`;
}
}
customElements.define('protected-page', ProtectedPage);
Ключевые моменты:
isAuthorized используется для условного
отображения контента через
<template is="dom-if">.connectedCallback) предотвращает несанкционированный
доступ.redirect-login позволяют централизованно
управлять маршрутизацией.В Polymer важным инструментом для авторизации является система событий и реактивные свойства компонентов. Используя события, можно уведомлять другие части приложения о смене состояния авторизации, например, при успешном входе или выходе:
this.dispatchEvent(new CustomEvent('logout', { bubbles: true, composed: true }));
bubbles: true позволяет событию подниматься по дереву
компонентов.composed: true делает событие доступным за пределами
Shadow DOM.Это упрощает централизованное управление состоянием авторизации и обеспечивает взаимодействие между отдельными компонентами без глобальных переменных.
Polymer-компоненты легко интегрируются с внешними сервисами аутентификации через OAuth 2.0 или OpenID Connect. Основная стратегия заключается в открытии окна авторизации и обработке токена в колбеке:
handleOAuthLogin() {
const authWindow = window.open('https://auth.example.com/oauth2/authorize', 'auth', 'width=600,height=700');
window.addEventListener('message', (event) => {
if (event.origin === 'https://auth.example.com') {
sessionStorage.setItem('authToken', event.data.token);
this.dispatchEvent(new CustomEvent('login-success', { detail: event.data }));
}
});
}
Особенности:
window.postMessage обеспечивает
безопасную передачу токена между окнами.sessionStorage или
localStorage в зависимости от требований безопасности.dispatchEvent для
уведомления компонентов приложения о смене состояния пользователя.Для сложных приложений важно не только проверять факт аутентификации, но и контролировать права пользователя. Пример механизма ролей:
class RoleProtectedPage extends PolymerElement {
static get properties() {
return {
userRoles: { type: Array, value: () => [] },
requiredRole: { type: String }
};
}
connectedCallback() {
super.connectedCallback();
const token = sessionStorage.getItem('authToken');
if (token) {
this.userRoles = JSON.parse(atob(token.split('.')[1])).roles || [];
}
if (!this.userRoles.includes(this.requiredRole)) {
this.dispatchEvent(new CustomEvent('access-denied'));
}
}
}
Для надёжной работы аутентификации и авторизации необходимо учитывать:
sessionStorage.removeItem('authToken').Эти меры позволяют создавать безопасные и масштабируемые приложения на Polymer, обеспечивая корректную аутентификацию и детализированное управление правами пользователей.