Лучшие практики для JWT в Spring Boot: построение непроницаемой крепости безопасности
Лучшие практики для JWT в Spring Boot: построение непроницаемой крепости безопасности

Предисловие

Привет всем, я из сообщества разработчиков Tencent Cloud. Front_Yue,В этой статье мы расскажем, что такое JWT и как его использовать в JWT.

В современных веб-приложениях безопасность имеет решающее значение. Для аутентификации пользователей и защиты данных приложений мы обычно используем механизмы аутентификации и авторизации. JSON Web Token (JWT) — это открытый стандарт (RFC 7519), определяющий компактный, автономный способ безопасной передачи информации между сторонами в виде объекта JSON. Эти сообщения можно проверить и им можно доверять, поскольку они имеют цифровую подпись. JWT можно подписать с использованием алгоритма HMAC или пары открытого/закрытого ключей RSA или ECDSA.

В приложениях Spring Boot JWT часто используется как метод аутентификации без сохранения состояния, позволяющий клиенту использовать JWT при каждом запросе аутентификации.

Текстовый контент

1. Структура JWT

JWT обычно состоит из трех частей,использовать между ними.отдельный,следующее:

Язык кода:java
копировать
xxxxx.yyyyy.zzzzz
1. Заголовок

Обычно содержит две части информации:

  • Тип токена, в данном случае JWT.
  • Используемый алгоритм подписи, например HMAC SHA256 или RSA.

Например:

Язык кода:json
копировать
{
  "alg": "HS256",
  "typ": "JWT"
}

Этот объект JSON закодирован Base64Url и образует первую часть JWT.

2. Полезная нагрузка

Содержит заявление. Утверждения — это утверждения об объектах (обычно пользователях) и других данных. Существует три типа претензий: зарегистрированные претензии, публичные претензии и частные претензии.

Например:

Язык кода:json
копировать
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

Этот объект JSON также закодирован Base64Url и образует вторую часть JWT.

3. Подпись

Это подпись двух вышеупомянутых частей контента, предотвращающая подделку контента.

Эта часть является сигнатурой первых двух частей и требует указания секрета. Этот ключ известен только серверу и должен храниться в секрете. Сервер использует этот ключ для подписи заголовка и полезных данных при создании токена и генерирует третью часть. Клиент приносит этот JWT со своим запросом, а сервер использует тот же ключ для проверки.

2. Использование JWT в Spring Boot

В Spring Boot вы можете интегрировать JWT, выполнив следующие действия:

1. Добавьте зависимости

первый,существоватьpom.xmlДобавитьJWTсвязанные зависимости,нравитьсяjjwt

Язык кода:xml
копировать
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
2. Создайте класс инструмента JWT.

Нам нужно создать в проекте класс инструмента Java для генерации и проверки JWT:

Язык кода:java
копировать
public class JwtUtils {

    private static final String SECRET = "your_secret_key"; // ключ
    private static final long JWT_EXPIRATION = 604800000; // Срок действия одна неделя
    // Создать токен JWT
    public static String generateToken(String username) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + JWT_EXPIRATION);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
    }
    // Проверьте токен JWT
    public static Claims validateToken(String token) {
        try {
            return Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            // Срок действия JWT истекает
            e.printStackTrace();
        } catch (UnsupportedJwtException e) {
            // Неподдерживаемый JWT
            e.printStackTrace();
        } catch (MalformedJwtException e) {
            // Ошибка формата JWT
            e.printStackTrace();
        } catch (SignatureException e) {
            // Подпись JWT несовместима
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // JWT пуст или имеет неверный формат.
            e.printStackTrace();
        }
        return null;
    }
}
3. Создайте фильтры аутентификации.

В проекте нам необходимо создать фильтр для перехвата запросов, отправленных клиентом, а серверу необходимо проверить корректность парсинга JWT.

Язык кода:java
копировать
@Component
public class JwtAuthenticationFilter extends Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Операция инициализации, опционально
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String tokenHeader = httpRequest.getHeader("Authorization");

        if (tokenHeader == null || !tokenHeader.startsWith("Bearer ")) {
            chain.doFilter(request, response);
            return;
        }

        // Получите токен и подтвердите
        String token = tokenHeader.substring(7);
        Claims claims = JwtUtils.validateToken(token);

        if (claims == null) {
            // Проверка не удалась, обработка ситуаций без аутентификации
            // Например: Возвращает 401 Неавторизованный код статуса.
        } else {
            // Проверка прошла успешно, установите данные для аутентификации пользователя.
            UserDetails userDetails = // Получите UserDetails на основе информации в заявках.
            UsernamePasswordAuthenticationToken authentication =
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }

        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // Операция уничтожения, опционально
    }
}

В приведенном выше коде,Мы создалиJwtAuthenticationFilter,Он будет запускаться перед каждым запросом,Проверьте, содержит ли заголовок запроса клиента действительный JWT. если содержит,Он извлечет информацию о пользователе из JWT.,и использоватьSecurityContextHolderЧтобы установить текущего аутентифицированного пользователя。

4. Создайте интерфейс входа пользователя.

когда пользователь входит в систему,Можно использоватьJwtUtilsгенерироватьJWT,и вернуть его клиенту. Клиент должен сохранить этот JWT локально.,Убедитесь, что вы настроили логику генерации и проверки JWT.,включая созданиеJWTКласс инструмента(JwtUtils)и для хранения и проверкиJWTинформационныйключ,Ниже приведен пример интерфейса входа в систему, который я создал.,Только для справки.

Язык кода:java
копировать
@Api(tags = «Управление списком пользователей»)
@RestController
public class SysUserController extends BaseController {
    @ApiOperation("Вход по учетной записи и паролю")
    @GetMapping("/login")
    public AjaxResult login(@RequestParam String userName, @RequestParam String password) {
        if (userName != null && password != null) {
            SysUser sysUser = new SysUser();
            sysUser.setUserName(userName);
            sysUser.setPassword(newPassword);
            List<SysUser> user = sysUserService.list(sysUser);
            if (user.size() == 1) {
                return success(setUserInfo(user.get(0)));
            } else {
                return error("Имя пользователя или пароль неверны");
            }
        } else {
            return error("Имя пользователя или пароль не могут быть пустыми");
        }
    }


    public Map<String, Object> setUserInfo(SysUser userInfo) {
        String jwt = JwtUtil.createToken(userInfo.getUserId(), userInfo.getUserName(), userInfo.getOpenid()); //jwt содержит информацию о вошедшем в систему сотруднике
        loginInfo.setUserId(userInfo.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("userinfo", userInfo);
        map.put("token", jwt);
        return map;
    }
}

3. Клиентское хранение и использование JWT

После того, как клиент (например, интерфейсное приложение) успешно войдет в систему,,После получения JWT,должен Воляего сохранениесуществоватьlocalStoragesessionStorageилиcookiesсередина。существоватьпоследующие запросысередина,Клиент должен пройтиHTTPЗаголовок запроса(нравитьсяAuthorization)ВоляJWTОтправлено на сервер для проверки。

1. Сохраните токен JWT
Язык кода:js
копировать
const handleLogin = async () => {
  if (user.validCode == validCode.value) {
    const res: any = await login(user);
    if (res.code == 200) {
      sessionStorage.setItem("token", res.data.token);
      store.setUserInfo(res.data.userinfo);
    }
  }
}  
2. Используйте токены JWT
Язык кода:js
копировать
// перехватчик запросов
service.interceptors.request.use(config => {
    // Перед отправкой каждого запроса определите, есть ли токен в vuex.        
    // Если он существует, токен будет добавлен в заголовок HTTP-запроса, чтобы фон определял ваш статус входа на основе токена.
    // Даже если токен существует локально, возможно, срок действия токена истек, поэтому статус возврата должен оцениваться в перехватчике ответа. 
    config.headers['Authorization'] = 'Bearer ' + sessionStorage.getItem('token');
    return config;
}, error => {
    Promise.reject(error);
})

4. Обновить токен

Чтобы повысить безопасность, вы можете рассмотреть возможность реализации механизма токена обновления. Долгосрочные токены (токены доступа) обычно имеют более короткий срок действия, тогда как токены обновления (токены обновления) имеют более длительный срок действия. По истечении срока действия токена доступа клиент может использовать токен обновления для получения нового токена доступа, не требуя от пользователя повторного входа в систему.

5. Обработка истечения срока действия JWT

Когда срок действия токена JWT клиента истечет, запросы, которые мы отправляем через клиент, будут отклонены. Вам необходимо разработать механизм для обработки этой ситуации, например, предложить пользователю снова войти в систему или автоматически использовать токен обновления для получения нового токена доступа.

Подвести итог

Использование JWT для аутентификации и авторизации пользователей обеспечивает гибкость и масштабируемость, упрощая управление сеансами пользователей приложениям с отдельными внешними и внутренними компонентами. Правильно настроив класс инструмента JWT, мы можем легко реализовать аутентификацию JWT в приложениях Spring Boot. Убедитесь, что ваши ключи JWT хранятся надежно и часто заменяются, чтобы предотвратить потенциальные угрозы безопасности.

Наконец, я хотел бы поблагодарить моих друзей из сообщества разработчиков Tencent Cloud за их сотрудничество. Если вам нравится контент моего блога и вы цените мои взгляды и обмен опытом, ставьте лайки, собирайте и комментируйте. Это будет моей самой большой поддержкой и поощрением. В то же время я также приветствую ценные комментарии и предложения каждого, чтобы я мог лучше улучшить и усовершенствовать свой блог. Спасибо!

Я участвую в последнем конкурсе эссе для специального учебного лагеря Tencent Technology Creation 2024. Приходите и разделите со мной приз!

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.