JavaScript · API · Средний

Токен-аутентификация

5 задач

Регистрируйте пользователя, получайте токен и выполняйте аутентифицированные API-запросы.

Поток токен-аутентификации

#
**Краткий способ написать fetch-вызовы** В секции Beginner каждый запрос через fetch использовал две отдельные строки `await`: ```javascript const response = await fetch(url); const data = await response.json(); ``` Далее вы также увидите однострочную сокращённую запись с `.then()`: ```javascript const data = await fetch(url).then(r => r.json()); ``` Эти два записи равнозначны. `.then(r => r.json())` — это колбэк, прикреплённый напрямую к Promise, возвращаемому `fetch()`. Когда сервер отвечает, `.then()` немедленно вызывает `r.json()` и возвращает новый Promise. Внешний `await` ждёт выполнения этого JSON Promise. Сокращённая запись удобна, когда не нужно проверять `response.status` или `response.ok` перед чтением тела. Когда нужна проверка ошибок, используйте двухшаговый вариант — он даёт доступ к `response` до чтения тела: ```javascript const response = await fetch(url); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); ``` --- Токен-аутентификация работает в два шага: получить токен один раз, затем включать его в каждый последующий запрос. **Шаг 1 — Зарегистрировать нового пользователя:** ```javascript const response = await fetch('https://apilearn.tukas.dev/api/auth/register/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'alice42', email: '[email protected]', password: 'SecurePass123!', }), }); const data = await response.json(); console.log(data.token); // токен возвращается сразу при регистрации ``` **Шаг 2 — Или войти для получения токена существующего аккаунта:** ```javascript const response = await fetch('https://apilearn.tukas.dev/api/auth/token/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'alice42', password: 'SecurePass123!' }), }); const { token } = await response.json(); ``` **Шаг 3 — Использовать токен в заголовке `Authorization`:** ```javascript const headers = { 'Authorization': `Token ${token}`, 'Content-Type': 'application/json', }; const profile = await fetch('https://apilearn.tukas.dev/api/users/profile/', { headers, }).then(r => r.json()); console.log(profile.username); ``` Токен не истекает — сохраняйте и переиспользуйте его между запросами. Формат заголовка `Authorization` — ровно `Token <token>` (с заглавной T, пробел, затем значение токена).

Регистрация, токен и аутентифицированные запросы

#
Полный поток — регистрация, получение токена, выполнение аутентифицированных запросов: ```javascript const BASE_URL = 'https://apilearn.tukas.dev'; async function register(username, email, password) { const response = await fetch(`${BASE_URL}/api/auth/register/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, email, password }), }); if (!response.ok) { const err = await response.json(); throw new Error(JSON.stringify(err)); } return response.json(); // { token, user: { id, username, email } } } async function getToken(username, password) { const response = await fetch(`${BASE_URL}/api/auth/token/`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); const data = await response.json(); return data.token; } async function main() { // Получаем токен для существующего аккаунта const token = await getToken('YOUR_USERNAME', 'YOUR_PASSWORD'); console.log('Токен:', token); // Строим заголовки аутентификации const headers = { 'Authorization': `Token ${token}`, 'Content-Type': 'application/json', }; // Получаем профиль const profile = await fetch(`${BASE_URL}/api/users/profile/`, { headers }) .then(r => r.json()); console.log('Авторизован как:', profile.username); console.log('Email:', profile.email); } main(); ``` Переиспользуемый помощник для аутентифицированных запросов: ```javascript function makeAuthHeaders(token) { return { 'Authorization': `Token ${token}`, 'Content-Type': 'application/json', }; } const token = await getToken('YOUR_USERNAME', 'YOUR_PASSWORD'); const headers = makeAuthHeaders(token); const cart = await fetch(`${BASE_URL}/api/cart/`, { headers }).then(r => r.json()); console.log('Товаров в корзине:', cart.items.length); ```

Справочник токен-аутентификации

#
**Эндпоинты** ``` POST /api/auth/register/ Регистрация + получение токена тело: { username, email, password } возвращает: { token, user: { id, username, email } } POST /api/auth/token/ Получить токен для существующего пользователя тело: { username, password } возвращает: { token } ``` **Использование токена** ```javascript headers: { 'Authorization': `Token ${token}` } // Формат: "Token " + значение токена (заглавная T, один пробел) ``` **Требования к паролю** ``` Минимум 8 символов Минимум одна заглавная буква Минимум одна цифра Минимум один специальный символ (!, @, #, ...) ``` **401 Unauthorized** ```javascript const response = await fetch(url, { headers }); if (response.status === 401) { console.log('Недействительный или отсутствующий токен'); } ``` **Эндпоинты, требующие аутентификации** ``` GET/PATCH/PUT /api/users/profile/ GET/POST /api/cart/items/ PATCH/DELETE /api/cart/items/{id}/ POST/GET /api/orders/ ```
01

Получить токен аутентификации

#

POST к `/api/auth/token/` с вашими учётными данными. Выведите полученный токен.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // POST /api/auth/token/ с username и password
  // вывести токен
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  });
  const data = await response.json();
  console.log(data.token);
}

main();
02

Получить свой профиль

#

Получите токен, затем используйте его для запроса к `/api/users/profile/`. Выведите `username` и `email`.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // 1. получить токен
  // 2. GET /api/users/profile/ с заголовком Authorization
  // 3. вывести username и email
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const profile = await fetch(`${BASE_URL}/api/users/profile/`, {
    headers: { 'Authorization': `Token ${token}` },
  }).then(r => r.json());

  console.log(profile.username);
  console.log(profile.email);
}

main();
03

Что происходит без токена

#

Попробуйте запросить `/api/users/profile/` без заголовка Authorization. Выведите `response.status` и `response.ok`. Затем повторите с действительным токеном и сравните.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // 1. запросить профиль без авторизации — вывести status и ok
  // 2. запросить профиль с действительным токеном — вывести status и ok
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // Without token
  const r1 = await fetch(`${BASE_URL}/api/users/profile/`);
  console.log('No token:', r1.status, r1.ok);  // 401 false

  // With token
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
  }).then(r => r.json());

  const r2 = await fetch(`${BASE_URL}/api/users/profile/`, {
    headers: { 'Authorization': `Token ${token}` },
  });
  console.log('With token:', r2.status, r2.ok);  // 200 true
}

main();
04

Зарегистрировать нового пользователя

#

Зарегистрируйте нового пользователя, отправив POST к `/api/auth/register/`. Используйте уникальное имя. Выведите токен и username из ответа.

const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  // POST /api/auth/register/ с username, email, password
  // вывести token и username
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function main() {
  const response = await fetch(`${BASE_URL}/api/auth/register/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      username: 'newuser_' + Date.now(),
      email: '[email protected]',
      password: 'SecurePass123!',
    }),
  });
  const data = await response.json();
  console.log(data.token);
  console.log(data.user.username);
}

main();
05

Вспомогательная функция аутентификации

#

Напишите async-функцию `getAuthHeaders(username, password)`, которая получает токен и возвращает объект заголовков `{ Authorization: "Token ..." }`. Используйте её для запроса профиля и корзины.

const BASE_URL = 'https://apilearn.tukas.dev';

async function getAuthHeaders(username, password) {
  // получить токен, вернуть объект заголовков
}

async function main() {
  const headers = await getAuthHeaders('YOUR_USERNAME', 'YOUR_PASSWORD');
  // использовать headers для запроса профиля и корзины
}

main();
Решение
const BASE_URL = 'https://apilearn.tukas.dev';

async function getAuthHeaders(username, password) {
  const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ username, password }),
  }).then(r => r.json());
  return { 'Authorization': `Token ${token}` };
}

async function main() {
  const headers = await getAuthHeaders('YOUR_USERNAME', 'YOUR_PASSWORD');

  const profile = await fetch(`${BASE_URL}/api/users/profile/`, { headers }).then(r => r.json());
  console.log('Profile:', profile.username);

  const cart = await fetch(`${BASE_URL}/api/cart/`, { headers }).then(r => r.json());
  console.log('Cart items:', cart.items.length);
}

main();