はじめに
Webアプリケーションの特定セッションを外部から切断したくなったことはありませんか?
「危険なヤツ発見! とりあえず切断」
みたいな。
しかもWebアプリケーションには手を入れずに・・・
対象はSpring-Sessionを使ったWebアプリケーションでセッションをRedisに保持しています。
それなら単純に
「Redisからセッション情報を消してしまえ」
と考えた訳です。うまくいくか実験してみます。
もっとスマートな方法を知っている方、ご指摘いただければ幸いです。
制限事項など
本記事の内容は以下の環境で動作確認しております。
- java version "11.0.7" 2020-04-14 LTS
- Docker Desktop 2.2.0.5
- Windows 10 + MINGW32(git-bash)
(Macでも動作確認中 多分動くと思います)
Redisを準備
Redisの準備はDockerが簡単です。こちらを利用させていただきました。
docker-composeでredis環境をつくる
$ docker-compose up -d
で、Redisを起動しておきます。
※もちろん、使用しているOSに直接Redisをインストールしても構いません。
Spring-Sessionアプリケーションの準備
Spring-Sessionアプリケーションがなければ実験できませんが、いい感じに単純なサンプルアプリが見つかりません。そこで簡単なアプリを作製して以下に配置しました。
Sprint-Session-Sample
Spring-Session-Sampleの動作
1.ダウンロードもしくはクローンしたディレクトリでアプリを実行
$ ./gradlew bootRun
Redisのデフォルトポート(6379)に接続して、うまく起動すれば
上記の文字列が現れます。
2.http://localhost:8080/
にアクセス
各フィールドに文字列を入力して [next] ボタンを押すと
セッションを引き継いだ次の画面に入力した文字列が表示されます。
セッションが(デフォルト30分で)切れると、エラー画面の遷移します。
外部からの操作で、この状態を再現します。
Redisの観察と操作
Redisのどのようなアイテムが登録されてセッションを管理しているのかを観察します。
- redis-cliの利用
$ docker exec -it [CONTAINER ID] /bin/bash
root@[CONTAINER ID]:/data# redis-cli
127.0.0.1:6379> (ココにコマンド入力)
※CONTAINER IDはdocker ps
で確認してください。
まず、Redisをクリアしておきます。
127.0.0.1:6379> flushall
http://localhost:8080/
にアクセスして、Redisを確認すると・・・
127.0.0.1:6379> keys *
1) "spring:session:sessions:0b288446-d209-4ecc-bfc4-7adf405e68a7"
2) "spring:session:sessions:expires:0b288446-d209-4ecc-bfc4-7adf405e68a7"
3) "spring:session:expirations:1604421420000"
3つのアイテムが確認できます。
0b288446-d209-4ecc-bfc4-7adf405e68a7
はHttpSessionのセッションIDで実際に情報が保持されているのは、
1) "spring:session:sessions:0b288446-d209-4ecc-bfc4-7adf405e68a7"`
上記のアイテムの様です。
これを削除してしまえばセッションが切れる筈!
やってみよう
1.http://localhost:8080/
にアクセス
2. Redis確認とセッション削除
127.0.0.1:6379> keys *
1) "spring:session:sessions:0b288446-d209-4ecc-bfc4-7adf405e68a7"
2) "spring:session:sessions:expires:0b288446-d209-4ecc-bfc4-7adf405e68a7"
3) "spring:session:expirations:1604421420000"
セッション情報を削除
127.0.0.1:6379> del spring:session:sessions:0b288446-d209-4ecc-bfc4-7adf405e68a7
(integer) 1
127.0.0.1:6379> keys *
1) "spring:session:sessions:expires:0b288446-d209-4ecc-bfc4-7adf405e68a7"
2) "spring:session:expirations:1604421420000"
3.[next]ボタンを押してみる
セッションを強制切断できました。
残りの2アイテム
127.0.0.1:6379> keys *
1) "spring:session:sessions:expires:0b288446-d209-4ecc-bfc4-7adf405e68a7"
2) "spring:session:expirations:1604421420000"
についてはTTL(有効期限)が設定されているので、とりあえず放置でよいでしょう。