Ответ
Процесс аутентификации по схеме OAuth 2.0 с выдачей JWT-токена (поток Resource Owner Password Credentials или Authorization Code):
1. Запрос на получение токена: Клиентское приложение отправляет HTTP POST-запрос на эндпоинт аутентификации сервера авторизации (Authorization Server).
Пример тела запроса для потока Password Credentials:
POST /oauth/token HTTP/1.1
Host: auth-server.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic base64(client_id:client_secret)
grant_type=password&username=user&password=pass&scope=read write
2. Валидация учетных данных: Сервер авторизации:
- Проверяет
client_idиclient_secret(для confidential clients). - Аутентифицирует пользователя по
usernameиpassword(сверяя с БД, LDAP, etc.). - Проверяет запрошенные
scopeна соответствие правам клиента.
3. Генерация JWT-токена: Если валидация успешна, сервер создаёт JWT (JSON Web Token), состоящий из трёх частей:
- Header: Алгоритм подписи (например,
{"alg": "HS256", "typ": "JWT"}). - Payload (Claims): Данные (например,
{"sub": "123", "username": "john", "roles": ["USER"], "exp": 1678886400}). - Signature: Цифровая подпись, созданная с использованием секретного ключа (HMAC) или приватного ключа (RSA).
4. Отправка ответа клиенту: Сервер возвращает JSON-ответ с токеном и метаданными.
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def50200e2b4c...",
"scope": "read write"
}
5. Использование токена клиентом:
Клиент сохраняет токен (в памяти, localStorage или безопасных куках) и использует его для доступа к защищённым ресурсам (Resource Server), добавляя в заголовок:
GET /api/protected-resource HTTP/1.1
Host: api-server.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Пример кода на Spring Security (упрощённо):
@RestController
public class AuthController {
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(@RequestBody LoginRequest request) {
// 1. Аутентификация
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword())
);
// 2. Генерация JWT
String jwt = jwtTokenUtil.generateToken(authentication);
// 3. Ответ
return ResponseEntity.ok(new AuthResponse(jwt));
}
}
Важно: Поток password рекомендуется только для доверенных клиентов (например, собственные мобильные приложения). Для веб-приложений предпочтительнее поток Authorization Code с PKCE.