RedisによるJWT Blacklistの実装
jwtベースのユーザ認証を実施する際にログアウトを実施する必要があります.
Access TokenとRefresh Tokenは簡単に削除できます.
問題は、Access Tokenの有効期間がまだ有効で、誰かがログアウトしている場合でも使用できます.
もちろん、有効期限は短い(30分)ですが、Access TokenをBlacklistとして保存して有効期限を切れさせる機能を実装したいと思います!
公式ホームページの説明 Redisは、ソースコードを迅速にオープンするメモリキー値データ構造記憶領域である.Redisは異なるメモリデータ構造のセットを提供するため、さまざまなカスタムアプリケーションを簡単に作成できます.主なRedisの使用例には、キャッシュ、セッション管理、pub/sub、ランキングが含まれます.Redisは現在最も人気のあるキーストアで、BSDライセンスを持ち、最適化されたCコードで作成され、多くの開発言語をサポートしています. 今回プロジェクトをした時に初めて知り合った子供.
メモリ・データ・リポジトリであり、キャッシュ、セッション管理などによく使用されます.
これらの特性を利用してBlacklistを実装したい.
形式のTemplateを作成し、必要なフォーマットがあれば追加してbeanとして登録できます!
cache機能、redisConnectionFactoryフラクチャなど、他の機能を追加することもできます.
BlacklistにAccess Tokenを登録します.
登録するAccess Token、Objectの値と有効時間を入力します.
う!!!いいえ、このように登録されています.
Access Tokenを受信するたびにBlacklistが存在するかどうかをチェックするだけです.
今は本当に终わりました!!!
そうかと思ったらハハハハ
私はそれをこの状態に変えて、間違いを発見しました.
ホストとポートの指定を考えてもRedisプログラムをインストールして回るのでしょうか?
本当に取り付けて回す必要があることを知りました.
私は本当に馬鹿です.
バックグラウンドで実行したい場合は、-dオプションを追加できます!
私が運転してReidsに戻ったところ、logout機能が正常に動作していることがわかりました!
コードが簡単だとは思わなかった.
Redisを設定していないだけで少し笑わせる
Dockerとして簡単にインストールおよび実行できます.
実際のサーバに配備したり、事前にインストールしたりすることができます.
ユーザー認証が安全に行えるようになりました!!
https://wnwngus.tistory.com/65?category=894390 https://velog.io/@kenux/Redis-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8-Redis-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0
Access TokenとRefresh Tokenは簡単に削除できます.
問題は、Access Tokenの有効期間がまだ有効で、誰かがログアウトしている場合でも使用できます.
もちろん、有効期限は短い(30分)ですが、Access TokenをBlacklistとして保存して有効期限を切れさせる機能を実装したいと思います!
Redisとは?
公式ホームページの説明
メモリ・データ・リポジトリであり、キャッシュ、セッション管理などによく使用されます.
これらの特性を利用してBlacklistを実装したい.
スプリングにRedisを使う
依存性
implementation("org.springframework.boot:spring-boot-starter-data-redis")
bean登録
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
cache機能、redisConnectionFactoryフラクチャなど、他の機能を追加することもできます.
ログアウト機能
// AuthService
@Transactional
public void logout(String accessToken, String refreshToken) {
// 1. Access Token 검증
if (!tokenProvider.validateToken(accessToken)) {
throw new ApiException(BasicResponseMessage.UNAUTHORIZED);
}
// 2. Access Token 에서 authentication 을 가져옵니다.
Authentication authentication = tokenProvider.getAuthentication(accessToken);
// 3. DB에 저장된 Refresh Token 제거
Long userId = Long.parseLong(authentication.getName());
refreshTokenRepository.deleteById(userId);
// 4. Access Token blacklist에 등록하여 만료시키기
// 해당 엑세스 토큰의 남은 유효시간을 얻음
Long expiration = tokenProvider.getExpiration(accessToken);
redisUtil.setBlackList(accessToken, "access_token", expiration);
}
実際にログアウトして、データベースに格納されているRefreshTokenを削除します.BlacklistにAccess Tokenを登録します.
ブラックリスト機能
@Component
@RequiredArgsConstructor
public class RedisUtil {
private final RedisTemplate<String, Object> redisTemplate;
private final RedisTemplate<String, Object> redisBlackListTemplate;
public void set(String key, Object o, int minutes) {
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(o.getClass()));
redisTemplate.opsForValue().set(key, o, minutes, TimeUnit.MINUTES);
}
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
public boolean delete(String key) {
return redisTemplate.delete(key);
}
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
public void setBlackList(String key, Object o, Long milliSeconds) {
redisBlackListTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(o.getClass()));
redisBlackListTemplate.opsForValue().set(key, o, milliSeconds, TimeUnit.MILLISECONDS);
}
public Object getBlackList(String key) {
return redisBlackListTemplate.opsForValue().get(key);
}
public boolean deleteBlackList(String key) {
return redisBlackListTemplate.delete(key);
}
public boolean hasKeyBlackList(String key) {
return redisBlackListTemplate.hasKey(key);
}
}
Blacklistの登録は非常に簡単です.RedisTemplateにだけあります.登録するAccess Token、Objectの値と有効時間を入力します.
う!!!いいえ、このように登録されています.
Access Tokenを受信するたびにBlacklistが存在するかどうかをチェックするだけです.
ブラックリストが存在するかどうかを確認(ログアウト済みかどうかを確認)
// TokenProvider
public boolean validateToken(String token) {
try {
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
if(redisUtil.hasKeyBlackList(token)) {
return false;
}
return true;
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) {
....
}
}
既存のJWT検証を行う場合は、TokenがBlacklistに追加されていることを確認し、検証を行います.今は本当に终わりました!!!
そうかと思ったらハハハハ
私はそれをこの状態に変えて、間違いを発見しました.
redisconnectionfailureexception unable to connect to redis
こんなミスがあった瞬間???問題が起こると思っていた.ホストとポートの指定を考えてもRedisプログラムをインストールして回るのでしょうか?
本当に取り付けて回す必要があることを知りました.
私は本当に馬鹿です.
Dockerを使用してRedisをインストールして実行
docker run -i -t --name redis -p 6379:6379 redis:alpine
これだけ自分でRedisimageをダウンロードして実行バックグラウンドで実行したい場合は、-dオプションを追加できます!
私が運転してReidsに戻ったところ、logout機能が正常に動作していることがわかりました!
に感銘を与える
コードが簡単だとは思わなかった.
Redisを設定していないだけで少し笑わせる
Dockerとして簡単にインストールおよび実行できます.
実際のサーバに配備したり、事前にインストールしたりすることができます.
ユーザー認証が安全に行えるようになりました!!
コメントサイト
Reference
この問題について(RedisによるJWT Blacklistの実装), 我々は、より多くの情報をここで見つけました https://velog.io/@boo105/Redis-를-통한-JWT-Blacklist-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol