Python · API · Середній рівень

JWT-авторизація

5 завдань

Використовуйте JSON Web Tokens для авторизації, розберіться з access/refresh токенами та оновленням токена.

JWT — access і refresh токени

#
JWT (JSON Web Token) — це друга схема автентифікації, яку пропонує API поруч із токен-авторизацією. Головна відмінність: замість одного токена ви отримуєте два. - Access token — короткоживучий (хвилини або години). Надсилаєте його з кожним запитом. - Refresh token — довгоживучий (дні). Використовується лише для отримання нового access token, коли старий закінчується. Навіщо два токени? Якщо access token вкрадуть, ним можна скористатися лише нетривалий час. Refresh token залишається в безпеці, бо подорожує рідше — лише при оновленні доступу. Формат заголовка Authorization для JWT використовує 'Bearer' замість 'Token': ``` Authorization: Bearer <access_token> ``` У requests: ```python import requests BASE_URL = 'https://apilearn.tukas.dev' access_token = '...' headers = {'Authorization': f'Bearer {access_token}'} response = requests.get(f'{BASE_URL}/api/users/profile/', headers=headers) ``` Коли access token закінчується, не потрібно знову запитувати облікові дані у користувача. Надішліть refresh token на ендпоінт оновлення і отримаєте новий access token: ```python response = requests.post( f'{BASE_URL}/api/auth/jwt/refresh/', json={'refresh': refresh_token}, ) new_access = response.json()['access'] ``` Токен-авторизація проти JWT — коли що обирати: - Токен-авторизація простіша: один токен, зрозумілий заголовок, без управління терміном дії. - JWT безпечніший для тривалих сесій: access token швидко закінчується, зменшуючи ризик при перехопленні. Стандарт у сучасних мобільних застосунках та SPA. Для скриптів і короткочасної автоматизації токен-авторизація часто достатня. JWT стає важливим, коли ви будуєте щось, що залишається автентифікованим днями або тижнями.

Отримання та оновлення JWT токенів

#
Отримайте пару JWT (потрібен зареєстрований користувач — дивіться тему token-auth): ```python import requests BASE_URL = 'https://apilearn.tukas.dev' credentials = {'username': 'alice42', 'password': 'securepass123'} response = requests.post(f'{BASE_URL}/api/auth/jwt/', json=credentials) tokens = response.json() access = tokens['access'] refresh = tokens['refresh'] print('access:', access[:20], '...') print('refresh:', refresh[:20], '...') ``` Використовуйте access token для виклику захищеного ендпоінта: ```python headers = {'Authorization': f'Bearer {access}'} profile = requests.get(f'{BASE_URL}/api/users/profile/', headers=headers).json() print(profile['username']) # 'alice42' ``` Коли access token закінчується, використовуйте refresh token для отримання нового: ```python response = requests.post( f'{BASE_URL}/api/auth/jwt/refresh/', json={'refresh': refresh}, ) new_access = response.json()['access'] print('новий access token отримано') # Використовуйте новий access token для наступного запиту headers = {'Authorization': f'Bearer {new_access}'} ``` Практичний патерн — обгорніть процес авторизації у функції: ```python def get_tokens(username, password): response = requests.post( f'{BASE_URL}/api/auth/jwt/', json={'username': username, 'password': password}, ) return response.json()['access'], response.json()['refresh'] def refresh_access(refresh_token): response = requests.post( f'{BASE_URL}/api/auth/jwt/refresh/', json={'refresh': refresh_token}, ) return response.json()['access'] access, refresh = get_tokens('alice42', 'securepass123') headers = {'Authorization': f'Bearer {access}'} # ... пізніше, якщо access закінчився: access = refresh_access(refresh) ```

Довідник JWT

#
Ендпоінти JWT: ``` POST /api/auth/jwt/ Отримати пару access + refresh token тіло: {username, password} повертає: {access: '...', refresh: '...'} POST /api/auth/jwt/refresh/ Оновити access token тіло: {refresh: '...'} повертає: {access: '...', refresh: '...'} ``` Заголовок Authorization: ``` Authorization: Bearer <access_token> ``` Токен-авторизація проти JWT: ``` Токен-авт. JWT Заголовок Token <t> Bearer <t> Токенів 1 2 (access + refresh) Термін дії Немає за замов. Access закінч., refresh довгий Оновлення Не потрібно POST /api/auth/jwt/refresh/ Підходить для Скрипти, просте Довгі сесії, mobile, SPA ``` Приклад: ```python # Отримати токени r = requests.post(f'{BASE_URL}/api/auth/jwt/', json={'username': u, 'password': p}) access, refresh = r.json()['access'], r.json()['refresh'] # Використати headers = {'Authorization': f'Bearer {access}'} # Оновити r = requests.post(f'{BASE_URL}/api/auth/jwt/refresh/', json={'refresh': refresh}) access = r.json()['access'] ```
01

Отримати пару JWT токенів

#

Зробіть POST до /api/auth/jwt/ із логіном і паролем. Виведіть перші 30 символів і access, і refresh токенів.

import requests

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

credentials = {'username': 'ВАШ_ЛОГІН', 'password': 'ВАШ_ПАРОЛЬ'}

# Отримайте пару JWT і виведіть перші 30 символів кожного токена
Рішення
import requests

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

credentials = {'username': 'ВАШ_ЛОГІН', 'password': 'ВАШ_ПАРОЛЬ'}
response = requests.post(f'{BASE_URL}/api/auth/jwt/', json=credentials)
tokens = response.json()
print(tokens['access'][:30])
print(tokens['refresh'][:30])
02

Авторизація за схемою Bearer

#

Отримайте JWT access token і використайте його зі схемою Bearer для GET /api/users/profile/. Виведіть логін і email із відповіді.

import requests

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

# Отримайте access token, потім GET профілю з Authorization: Bearer <token>
Рішення
import requests

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

r = requests.post(f'{BASE_URL}/api/auth/jwt/', json={
    'username': 'ВАШ_ЛОГІН', 'password': 'ВАШ_ПАРОЛЬ',
})
access = r.json()['access']

headers = {'Authorization': f'Bearer {access}'}
profile = requests.get(f'{BASE_URL}/api/users/profile/', headers=headers).json()
print(profile['username'])
print(profile['email'])
03

Оновити access token

#

Отримайте пару JWT, а потім відразу використайте refresh token для отримання нового access token через POST /api/auth/jwt/refresh/. Виведіть новий access token (перші 30 символів).

import requests

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

# 1. Отримайте початкову пару токенів
# 2. Використайте refresh token для отримання нового access token
# 3. Виведіть перші 30 символів нового access token
Рішення
import requests

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

r = requests.post(f'{BASE_URL}/api/auth/jwt/', json={
    'username': 'ВАШ_ЛОГІН', 'password': 'ВАШ_ПАРОЛЬ',
})
refresh = r.json()['refresh']

r2 = requests.post(f'{BASE_URL}/api/auth/jwt/refresh/', json={'refresh': refresh})
new_access = r2.json()['access']
print(new_access[:30])
04

Написати get_access_token()

#

Напишіть функцію get_access_token(username, password), яка повертає свіжий JWT access token. Викличте її і виведіть результат.

import requests

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

def get_access_token(username, password):
    # POST до /api/auth/jwt/ і повернення access token
    pass

token = get_access_token('ВАШ_ЛОГІН', 'ВАШ_ПАРОЛЬ')
print(token[:30])
Рішення
import requests

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

def get_access_token(username, password):
    response = requests.post(
        f'{BASE_URL}/api/auth/jwt/',
        json={'username': username, 'password': password},
    )
    return response.json()['access']

token = get_access_token('ВАШ_ЛОГІН', 'ВАШ_ПАРОЛЬ')
print(token[:30])
05

Написати refresh_access()

#

Напишіть функцію refresh_access(refresh_token), яка повертає новий access token через ендпоінт оновлення. Потім напишіть невеликий скрипт, що отримує початкову пару і відразу оновлює access token, виводячи обидва (перші 20 символів кожного).

import requests

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

def refresh_access(refresh_token):
    # POST до /api/auth/jwt/refresh/ і повернення нового access token
    pass

# Отримайте початкову пару, потім оновіть
Рішення
import requests

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

def refresh_access(refresh_token):
    response = requests.post(
        f'{BASE_URL}/api/auth/jwt/refresh/',
        json={'refresh': refresh_token},
    )
    return response.json()['access']

r = requests.post(f'{BASE_URL}/api/auth/jwt/', json={
    'username': 'ВАШ_ЛОГІН', 'password': 'ВАШ_ПАРОЛЬ',
})
original_access = r.json()['access']
refresh_token = r.json()['refresh']

new_access = refresh_access(refresh_token)

print('оригінальний:', original_access[:20])
print('оновлений:', new_access[:20])