Как работает Access Token?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает 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 - это проверенный способ аутентификации:
- Защита - только авторизованные пользователи получают доступ
- Масштабируемость - сервер не хранит сессии, только проверяет подпись
- Мобильность - работает на мобильных приложениях
- Стандарт - используется везде (OAuth2, OpenID Connect)
Это основа для безопасных веб-приложений в современном интернете.