SpringBoot-Oauth2.0 (3) — схема хранения токенов

Spring Boot
SpringBoot-Oauth2.0 (3) — схема хранения токенов

предисловие

Предыдущий, храним Токен в реляционной БД.Если ваша система предъявляет высокие требования к времени отклика интерфейса аутентификации, то в реляционной БД запрос Токена точно будет узким местом. Так что делать? Если рассматривать только хранение токенов, что может заменить хранение реляционных данных?

Анализ хранилища токенов

Во-первых, данные в общей реляционной базе данных будут храниться на диске, а время в основном расходуется на операции ввода-вывода. Тогда мы можем решить проблему IO, поместив Токен в память, и, кстати, это также уменьшает сетевой запрос к базе данных.В фреймворке SpringBoot Oauth хранилище по умолчанию находится в памяти.

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

В-третьих, есть ли другие варианты? Давайте подумаем об этом с другой стороны, зачем нам хранить Токен? Поскольку токен выдается системой, это сертификат авторизации, который позволяет клиенту получить доступ к системе.Когда клиент использует токен для запроса ресурсов, система должна убедиться, что токен юридически авторизован, прежде чем разрешить клиенту доступ сопутствующие ресурсы. Можем ли мы также понять это таким образом, пока система может проверить авторизованный Токен, можно не сохранять его. На самом деле есть Токен, который можно хранить без хранения.Токен сам имеет информацию об авторизации.Системе нужно только использовать соответствующий алгоритм в памяти,чтобы проверить законно ли авторизован Токен.Этот метод заключается в использованииJWT.

Что такое ЮВТ?

JSON Web Token (JWT) – это решение для аутентификации. Клиент и сервер используют токен в формате, указанном JWT, для аутентификации и взаимодействия. Формат JWT разделен на три раздела, каждый раздел разделен знаком «.», и каждый раздел содержит разную информацию, конечно, функции тоже разные. Они есть:

Заголовок - заголовокФормат данных: данные JSON имеют кодировку Base64URL. Сообщение: указан тип шифрования, а тип — JWT.

Полезная нагрузка - Полезная нагрузкаФормат данных: данные JSON имеют кодировку Base64URL. Информация: информация об авторизации клиента и т. д.

Подпись - ПодписьОписание: Первые две части и согласованный секретный ключ генерируются указанным алгоритмом шифрования, также называемымКод проверки информации MAC, чтобы предотвратить подделку данных

Выше мы предложили 3 решения для замены Токена хранилища БД. Среди них первый был отработан в первой статье. Затем давайте попрактикуемся с двумя другими вариантами отдельно.

Токен хранится в Redis

Pom

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

настроить

spring:
  redis:
    host: {redis host}
    password: {redis password}

токен запроса

redis-请求token

Данные токена в Redis

redis-存储token

Видно, что в базу данных добавлено 4 новых ключа, так каковы же их значения? Глядя на данные напрямую, это все двоичные данные, и их нельзя увидеть. Затем мы возвращаемся к исходному коду, чтобы найти ответ. Найдите метод storeAccessToken класса OAuth2Authentication, мы видим, что значение ключа — это сериализованные двоичные данные экземпляра OAuth2Authentication, а значение других ключей — это двоичные данные, соответствующие токену.

Теперь токен хранится в нашем ожидаемом Redis, и, наконец, мы запросим ресурс, чтобы увидеть, может ли он пройти, и завершить проверку.

запросить ресурс

redis-请求资源

Примите ожидаемые результаты без каких-либо неожиданностей и сюрпризов.

Теперь, когда мы реализовали хранение токенов в Redis, оно на самом деле очень похоже на хранение в базе данных, просто замените TokenStore. Тогда продолжим практиковать схему JWT.

JWT

Pom

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-jwt</artifactId>
    </dependency>

настроить

JWT был кратко представлен выше, и на что мы должны обратить внимание в связи с настройкой, так это на то, что нам нужно согласовать секретный ключ и указать алгоритм, соответствующий JWT. Алгоритм JWT по умолчанию — HMACSHA256, найдите соответствующий валидатор в фреймворке.MacSigner

/**
* 配置jwt相关
* 省略了一部分代码
**/
@Configuration
@EnableAuthorizationServer
public class MyAuthorizationServerConfigurer extends AuthorizationServerConfigurerAdapter {

		// 指定加密秘钥
    @Value("${jwt.key:GoLdJwtKey}")
    private String tokenSecretKey;

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
				// 指定 token 转化器
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
      	// 设置加签秘钥
        jwtAccessTokenConverter.setSigningKey(tokenSecretKey);
      	// 设置信息验证码校验器
        jwtAccessTokenConverter.setVerifier(new MacSigner(tokenSecretKey));
        TokenStore tokenStore = new JwtTokenStore(jwtAccessTokenConverter);

        endpoints.accessTokenConverter(jwtAccessTokenConverter);
        endpoints.tokenStore(tokenStore);
    }
}

Получить токен

jwt-获取token

Этот токен слишком длинный. Полный токен выглядит следующим образом:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicmVzIl0sInNjb3BlIjpbIndyaXRlIl0sImV4cCI6MTU5OTIzNDM1OSwianRpIjoiYjQ2NmVkNDEtNWI1Ni00NDc2LWE4ZjctYjEwYjQ0MTFhNTViIiwiY2xpZW50X2lkIjoiZ29sZCJ9.P-510ioyW4mfjS_UFlCREqnCail2GfMHFx4Mc2Jjf4Q

Давайте взглянем на этот токен. В нем действительно три сегмента. Первые два сегмента можно напрямую декодировать с помощью Base64URL. то переходим непосредственно кофициальный сайт ДВТРасшифруйте это:

jwt-decode

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

запросить ресурс

jwt-请求资源

Все прошло хорошо, наш запрос на ресурсы был успешным.

Суммировать

Сегодня наша цель - найти решение для замены токена хранилища базы данных.После анализа мы нашли 3 решения и отработали их соответственно. Если ваше приложение является автономным, то Токен может напрямую использовать память, что очень удобно. Если ваше приложение является распределенным, то реляционная база данных является вариантом, если требования к производительности высоки, то перейдите на Redis. Однако производительность решения JWT также очень высока. Пока не храните его, он просто предоставляет некоторую авторизационную информацию. Вы можете контролировать время действия токена, потому что он не может быть признан недействительным на стороне сервера после его выдачи. , и это не является большой проблемой для производственного использования. После детального анализа конкретной ситуации выберите подходящий способ хранения Токена.

Личный уровень ограничен, приглашаю всех исправлять меня и общаться больше~~~

демо:GitHub.com/золотая тыква…