Впровадження управління токенами за допомогою Fetch у Next.js

У сучасній веб-розробці управління автентифікацією користувачів є критично важливим, особливо коли мова йде про RESTful API. Тут ми розглянемо, як керувати терміном дії токенів та їх оновленням у додатку Next.js, використовуючи рідний fetch API замість сторонніх бібліотек, таких як Axios.

Чому використовувати Fetch?

Використання fetch безпосередньо означає менше залежностей, що в свою чергу призводить до легшого пакету додатку та меншої вразливості до оновлень зовнішніх бібліотек.
``js
const response = await fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Authorization':
Bearer ${token}`
}
});

Ось як ми можемо це зробити:

Крок 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.access
    token;
    };

Розгляньте використання 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.access
token;
};

Перекладено з: Implementing Token Management with Fetch in Next.js

Leave a Reply

Your email address will not be published. Required fields are marked *