← Назад к вопросам

Как работает Access Token?

1.7 Middle🔥 181 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает Access Token

Access Token - это криптографический токен, который подтверждает, что пользователь авторизован и может получить доступ к защищенным ресурсам. Это один из основных механизмов аутентификации в современных веб-приложениях.

Базовая схема работы

1. Пользователь вводит логин/пароль
   ↓
2. Сервер проверяет данные
   ↓
3. Сервер создает Access Token
   ↓
4. Сервер отправляет токен клиенту
   ↓
5. Клиент сохраняет токен
   ↓
6. При каждом запросе клиент отправляет токен
   ↓
7. Сервер проверяет токен и обрабатывает запрос

Как это выглядит в коде

Шаг 1: Вход в систему

// Клиент отправляет учетные данные
const response = await fetch('/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'user@example.com', password: 'secret' })
})

const { access_token } = await response.json()
// Результат: { access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' }

Шаг 2: Сохранение токена

// Сохранить токен в localStorage или sessionStorage
localStorage.setItem('access_token', access_token)

// Или сохранить в памяти (менее безопасно, но быстрее)
let token = access_token

Шаг 3: Использование токена в запросах

// При каждом запросе отправляем токен в заголовке Authorization
const response = await fetch('/api/profile', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
    'Content-Type': 'application/json'
  }
})

const userData = await response.json()

Шаг 4: Проверка на сервере

// На сервере (например, FastAPI)
from fastapi import Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

security = HTTPBearer()

async def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
    token = credentials.credentials
    try:
        # Декодируем и проверяем подпись JWT
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        return payload
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail='Invalid token')

@app.get('/api/profile')
async def get_profile(payload = Depends(verify_token)):
    user_id = payload['sub']
    # Возвращаем данные пользователя
    return {'id': user_id, 'email': 'user@example.com'}

Структура JWT токена

Мост современных Access Token'ов используют JWT (JSON Web Token). JWT состоит из трех частей, разделенных точками:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
     ↑ Header                      ↑ Payload                  ↑ Signature

Header (заголовок)

{
  "alg": "HS256",
  "typ": "JWT"
}

Описывает тип токена и алгоритм подписи.

Payload (данные)

{
  "sub": "user_id_123",
  "email": "user@example.com",
  "role": "admin",
  "iat": 1640000000,
  "exp": 1640003600
}
  • sub - ID пользователя
  • email, role - данные пользователя
  • iat - когда создан (issued at)
  • exp - когда истекает (expiration)

Signature (подпись)

HMAC256(
  base64(header) + '.' + base64(payload),
  SECRET_KEY
)

Подпись предотвращает подделку. Если кто-то попытается изменить данные в токене, подпись не совпадет.

Время жизни токена

// Токен имеет время истечения (expires)
{
  "sub": "user_id",
  "iat": 1640000000,     // Создан
  "exp": 1640003600      // Истекает через 1 час
}

// Если токен истек, сервер вернет 401 Unauthorized
const response = await fetch('/api/profile', {
  headers: { 'Authorization': `Bearer ${expiredToken}` }
})
// response.status === 401

Refresh Token (обновление токена)

Так как Access Token'ы короткоживущие (1 час), используют Refresh Token для получения нового токена:

// Сервер выдает два токена
{
  "access_token": "eyJhbGc...",    // 1 час
  "refresh_token": "abcd1234..."   // 7 дней
}

// Когда access_token истек, используем refresh_token
const response = await fetch('/api/auth/refresh', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ refresh_token: localStorage.getItem('refresh_token') })
})

const { access_token } = await response.json()
localStorage.setItem('access_token', access_token)

Безопасность

Где хранить Access Token?

// ❌ Не хранить в localStorage (уязвимо для XSS)
localStorage.setItem('token', token)

// ✅ Хранить в httpOnly cookie (защищено от JavaScript)
// Сервер устанавливает: Set-Cookie: access_token=...; HttpOnly; Secure

// ✅ Хранить в памяти (исчезает при перезагрузке)
let token = response.data.access_token

Передача токена

// ✅ В заголовке Authorization (стандарт)
fetch('/api/data', {
  headers: { 'Authorization': `Bearer ${token}` }
})

// ❌ В URL параметре (видно в логах)
fetch(`/api/data?token=${token}`)

// ❌ В теле запроса (не стандартно)
fetch('/api/data', {
  body: JSON.stringify({ token })
})

Практический пример: React + Access Token

import { useEffect, useState } from 'react'

function Profile() {
  const [user, setUser] = useState(null)
  const [error, setError] = useState(null)

  useEffect(() => {
    const fetchProfile = async () => {
      const token = localStorage.getItem('access_token')
      
      try {
        const response = await fetch('/api/profile', {
          headers: { 'Authorization': `Bearer ${token}` }
        })

        if (response.status === 401) {
          // Токен истек, перенаправляем на вход
          window.location.href = '/login'
          return
        }

        const data = await response.json()
        setUser(data)
      } catch (err) {
        setError(err.message)
      }
    }

    fetchProfile()
  }, [])

  if (error) return <div>Ошибка: {error}</div>
  if (!user) return <div>Загрузка...</div>

  return <div>Привет, {user.name}!</div>
}

Вывод

Access Token - это проверенный способ аутентификации:

  1. Защита - только авторизованные пользователи получают доступ
  2. Масштабируемость - сервер не хранит сессии, только проверяет подпись
  3. Мобильность - работает на мобильных приложениях
  4. Стандарт - используется везде (OAuth2, OpenID Connect)

Это основа для безопасных веб-приложений в современном интернете.