Привет всем, я из сообщества разработчиков Tencent Cloud. Front_Yue,В этой статье мы расскажем, что такое JWT и как его использовать в JWT.
В современных веб-приложениях безопасность имеет решающее значение. Для аутентификации пользователей и защиты данных приложений мы обычно используем механизмы аутентификации и авторизации. JSON Web Token (JWT) — это открытый стандарт (RFC 7519), определяющий компактный, автономный способ безопасной передачи информации между сторонами в виде объекта JSON. Эти сообщения можно проверить и им можно доверять, поскольку они имеют цифровую подпись. JWT можно подписать с использованием алгоритма HMAC или пары открытого/закрытого ключей RSA или ECDSA.
В приложениях Spring Boot JWT часто используется как метод аутентификации без сохранения состояния, позволяющий клиенту использовать JWT при каждом запросе аутентификации.
JWT обычно состоит из трех частей,использовать между ними.
отдельный,следующее:
xxxxx.yyyyy.zzzzz
Обычно содержит две части информации:
Например:
{
"alg": "HS256",
"typ": "JWT"
}
Этот объект JSON закодирован Base64Url и образует первую часть JWT.
Содержит заявление. Утверждения — это утверждения об объектах (обычно пользователях) и других данных. Существует три типа претензий: зарегистрированные претензии, публичные претензии и частные претензии.
Например:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Этот объект JSON также закодирован Base64Url и образует вторую часть JWT.
Это подпись двух вышеупомянутых частей контента, предотвращающая подделку контента.
Эта часть является сигнатурой первых двух частей и требует указания секрета. Этот ключ известен только серверу и должен храниться в секрете. Сервер использует этот ключ для подписи заголовка и полезных данных при создании токена и генерирует третью часть. Клиент приносит этот JWT со своим запросом, а сервер использует тот же ключ для проверки.
В Spring Boot вы можете интегрировать JWT, выполнив следующие действия:
первый,существоватьpom.xml
ДобавитьJWTсвязанные зависимости,нравитьсяjjwt
:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
Нам нужно создать в проекте класс инструмента Java для генерации и проверки JWT:
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;
}
}
В проекте нам необходимо создать фильтр для перехвата запросов, отправленных клиентом, а серверу необходимо проверить корректность парсинга JWT.
@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
Чтобы установить текущего аутентифицированного пользователя。
когда пользователь входит в систему,Можно использоватьJwtUtils
генерироватьJWT,и вернуть его клиенту. Клиент должен сохранить этот JWT локально.,Убедитесь, что вы настроили логику генерации и проверки JWT.,включая созданиеJWTКласс инструмента(JwtUtils
)и для хранения и проверкиJWTинформационныйключ,Ниже приведен пример интерфейса входа в систему, который я создал.,Только для справки.
@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;
}
}
После того, как клиент (например, интерфейсное приложение) успешно войдет в систему,,После получения JWT,должен Воляего сохранениесуществоватьlocalStorage
、sessionStorage
илиcookiesсередина。существоватьпоследующие запросысередина,Клиент должен пройтиHTTPЗаголовок запроса(нравитьсяAuthorization
)ВоляJWTОтправлено на сервер для проверки。
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);
}
}
}
// перехватчик запросов
service.interceptors.request.use(config => {
// Перед отправкой каждого запроса определите, есть ли токен в vuex.
// Если он существует, токен будет добавлен в заголовок HTTP-запроса, чтобы фон определял ваш статус входа на основе токена.
// Даже если токен существует локально, возможно, срок действия токена истек, поэтому статус возврата должен оцениваться в перехватчике ответа.
config.headers['Authorization'] = 'Bearer ' + sessionStorage.getItem('token');
return config;
}, error => {
Promise.reject(error);
})
Чтобы повысить безопасность, вы можете рассмотреть возможность реализации механизма токена обновления. Долгосрочные токены (токены доступа) обычно имеют более короткий срок действия, тогда как токены обновления (токены обновления) имеют более длительный срок действия. По истечении срока действия токена доступа клиент может использовать токен обновления для получения нового токена доступа, не требуя от пользователя повторного входа в систему.
Когда срок действия токена JWT клиента истечет, запросы, которые мы отправляем через клиент, будут отклонены. Вам необходимо разработать механизм для обработки этой ситуации, например, предложить пользователю снова войти в систему или автоматически использовать токен обновления для получения нового токена доступа.
Использование JWT для аутентификации и авторизации пользователей обеспечивает гибкость и масштабируемость, упрощая управление сеансами пользователей приложениям с отдельными внешними и внутренними компонентами. Правильно настроив класс инструмента JWT, мы можем легко реализовать аутентификацию JWT в приложениях Spring Boot. Убедитесь, что ваши ключи JWT хранятся надежно и часто заменяются, чтобы предотвратить потенциальные угрозы безопасности.
Наконец, я хотел бы поблагодарить моих друзей из сообщества разработчиков Tencent Cloud за их сотрудничество. Если вам нравится контент моего блога и вы цените мои взгляды и обмен опытом, ставьте лайки, собирайте и комментируйте. Это будет моей самой большой поддержкой и поощрением. В то же время я также приветствую ценные комментарии и предложения каждого, чтобы я мог лучше улучшить и усовершенствовать свой блог. Спасибо!