Ответ
Процесс получения JWT (JSON Web Token) следует стандартному flow аутентификации:
Основные шаги:
-
Клиент отправляет учетные данные.
- Обычно
POST-запрос на эндпоинт/loginили/oauth/token. - Тело запроса содержит
username/password,client_id/client_secret(для OAuth2) или refresh token.POST /api/auth/login HTTP/1.1 Content-Type: application/json { "username": "user@example.com", "password": "secure_password" }
- Обычно
-
Сервер аутентификации проверяет данные.
- Валидирует логин/пароль в БД или через внешний провайдер (LDAP, OIDC).
- Проверяет активность учетной записи и права доступа.
-
Сервер генерирует и подписывает JWT.
- Header: Определяет алгоритм подписи (например,
HS256илиRS256). - Payload (Claims): Содержит данные (sub, roles,
exp— время истечения,iat— время выдачи). - Signature: Создается путем подписи
header.payloadсекретным ключом (HMAC) или приватным ключом (RSA).
- Header: Определяет алгоритм подписи (например,
-
Сервер возвращает токен клиенту.
- Чаще всего в теле ответа как JSON-объект.
{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_in": 3600 }
- Чаще всего в теле ответа как JSON-объект.
Пример на Spring Security (упрощенно):
// Конфигурация сервера (используя Password Grant)
@Configuration
@EnableAuthorizationServer
public class AuthConfig extends AuthorizationServerConfigurerAdapter {
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("clientapp")
.secret(passwordEncoder().encode("secret"))
.authorizedGrantTypes("password", "refresh_token")
.scopes("read", "write");
}
}
// Клиентский запрос (с помощью RestTemplate или WebClient)
HttpHeaders headers = new HttpHeaders();
headers.setBasicAuth("clientapp", "secret");
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "password");
body.add("username", "user");
body.add("password", "pass");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);
ResponseEntity<Map> response = restTemplate.postForEntity(
"http://auth-server/oauth/token",
request,
Map.class
);
String jwt = (String) response.getBody().get("access_token");
Best Practices:
- Всегда используйте HTTPS.
- Храните секретные ключи в безопасном хранилище (не в коде).
- Устанавливайте разумное время жизни токена (
expires_in). - Для хранения на клиенте предпочтительны HttpOnly, Secure куки.