У сучасній веб-розробці управління автентифікацією користувачів є критично важливим, особливо коли мова йде про RESTful API. Тут ми розглянемо, як керувати терміном дії токенів та їх оновленням у додатку Next.js, використовуючи рідний fetch API замість сторонніх бібліотек, таких як Axios.
Чому використовувати Fetch?
Використання fetch безпосередньо означає менше залежностей, що в свою чергу призводить до легшого пакету додатку та меншої вразливості до оновлень зовнішніх бібліотек.
``js
Bearer ${token}`
const response = await fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Authorization':
}
});
Ось як ми можемо це зробити:
Крок 1: Механізм оновлення токена
Спочатку нам потрібно створити функцію для оновлення нашого токена доступу:
const refreshToken = async () => {
// припускаємо, що ви зберігаєте свій refresh токен у cookie з атрибутом httponly
const response = await fetch('/api/refresh_token', {
method: 'POST',
credentials: 'include',
});
if (!response.ok) throw new Error('Не вдалося оновити токен');
const data = await response.json();
return data.access_token; // Припускаємо, що ваш бекенд повертає новий токен доступу
};
Ця функція робить POST запит до серверного ендпойнта для оновлення токена.
Крок 2: Створення обгортки для fetch
Ми обгорнемо fetch у власну функцію для перевірки токена та його оновлення:
const logout = () => {
// Очистити токен
localStorage.removeItem('accessToken');
// Перенаправити на сторінку входу
window.location.href = '/login';
};
const fetchWithAuth = async (url, options = {}) => {
let accessToken = localStorage.getItem('accessToken');
if (!accessToken) {
try {
accessToken = await refreshToken();
localStorage.setItem('accessToken', accessToken);
} catch (error) {
logout();
return; // Вийти, якщо не вдалося отримати новий токен
}
}
options.headers = {
...options.headers,
'Authorization': `Bearer ${accessToken}`
};
const response = await fetch(url, options);
if (response.status === 401) { // Токен вичерпав термін
try {
const newAccessToken = await refreshToken();
localStorage.setItem('accessToken', newAccessToken);
options.headers['Authorization'] = `Bearer ${newAccessToken}`;
return fetch(url, options); // Повторити запит з новим токеном
} catch (error) {
logout();
return; // Вийти, якщо оновлення не вдалося
}
}
return response;
};
Як це працює:
- Перевірка токена: Якщо токена немає, намагаємося його оновити.
- Додавання токена до заголовків: Включаємо токен у заголовки запиту.
- Обробка 401 (Unauthorized): Якщо сервер повертає 401, це може означати, що токен вичерпав термін, тому ми намагаємося його оновити та повторюємо запит.
- Вихід у разі помилки: Якщо оновлення токена не вдалося, виконуємо вихід користувача, щоб уникнути потрапляння в нескінченний цикл неавторизованого доступу.
Використання обгортки
Тепер використовуйте fetchWithAuth замість fetch для авторизованих запитів:
const exampleCall = async () => {
try {
const response = await fetchWithAuth('your-protected-endpoint', {
method: 'GET',
});
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Помилка:', error);
}
};
Урахування
- Безпека: Зберігання токенів у localStorage може бути не ідеальним для всіх сценаріїв.
```js
const refreshToken = async () => {
const response = await fetch('/api/refreshtoken', {
method: 'POST',
credentials: 'include',
});
if (!response.ok) throw new Error('Failed to refresh token');
const data = await response.json();
return data.accesstoken;
};
Розгляньте використання httpOnly cookie або більш безпечних методів зберігання.
- Обробка помилок: У наведеному коді відбувається вихід користувача при невдачі оновлення токена, але ви можете обробити це по-іншому, наприклад, відображенням повідомлення про помилку для користувача.
- Проектування API: Переконайтеся, що ваш бекенд має ендпойнти для оновлення токенів і безпечно обробляє ці запити.
Висновок
Імплементація управління токенами за допомогою fetch у Next.js дозволяє зробити ваш додаток легким, при цьому забезпечуючи надійну обробку автентифікації. Цей метод мінімізує зовнішні залежності, що може бути значною перевагою з точки зору безпеки та продуктивності.
Пам'ятайте, що важливо не тільки впроваджувати ці механізми, але й постійно тестувати потік автентифікації, щоб забезпечити найвищий рівень безпеки та користувацького досвіду.
```js
const refreshToken = async () => {
const response = await fetch('/api/refreshtoken', {
method: 'POST',
credentials: 'include',
});
if (!response.ok) throw new Error('Failed to refresh token');
const data = await response.json();
return data.accesstoken;
};
Перекладено з: Implementing Token Management with Fetch in Next.js