Spring-Sessionのセッションをぶった切る

# はじめに
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環境をつくる](https://qiita.com/uggds/items/5e4f8fee180d77c06ee1)

``` shell
$ docker-compose up -d 
```
で、Redisを起動しておきます。

※もちろん、使用しているOSに直接Redisをインストールしても構いません。

# Spring-Sessionアプリケーションの準備
Spring-Sessionアプリケーションがなければ実験できませんが、いい感じに単純なサンプルアプリが見つかりません。そこで簡単なアプリを作製して以下に配置しました。
[Sprint-Session-Sample](https://github.com/Be-cricket/Spring-Session-Sample)

### Spring-Session-Sampleの動作
#### 1.ダウンロードもしくはクローンしたディレクトリでアプリを実行

``` shell
$ ./gradlew bootRun
```
Redisのデフォルトポート(6379)に接続して、うまく起動すれば

``` Started SSSApplication in XXXX seconds
```
上記の文字列が現れます。

#### 2.`http://localhost:8080/` にアクセス
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338832/366f0f7f-846e-366f-7b60-ea02556c394f.png)
各フィールドに文字列を入力して　[next]　ボタンを押すと
セッションを引き継いだ次の画面に入力した文字列が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338832/185a98ae-e2d5-0f24-2f6e-c555e745cda5.png)
セッションが（デフォルト30分で）切れると、エラー画面の遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338832/45e4ac86-2293-7de6-7374-18581b56dffb.png)
外部からの操作で、この状態を再現します。

# Redisの観察と操作
Redisのどのようなアイテムが登録されてセッションを管理しているのかを観察します。

- redis-cliの利用

``` shell
$ docker exec -it [CONTAINER ID] /bin/bash
root@[CONTAINER ID]:/data# redis-cli
127.0.0.1:6379> （ココにコマンド入力）
```
※CONTAINER IDは`docker ps`で確認してください。
まず、Redisをクリアしておきます。

``` shell
127.0.0.1:6379> flushall
```
`http://localhost:8080/` にアクセスして、Redisを確認すると・・・

```shell
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で実際に情報が保持されているのは、

```shell
1) "spring:session:sessions:0b288446-d209-4ecc-bfc4-7adf405e68a7"`
```
上記のアイテムの様です。
これを削除してしまえばセッションが切れる筈！

# やってみよう
#### 1.`http://localhost:8080/` にアクセス
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338832/366f0f7f-846e-366f-7b60-ea02556c394f.png)

#### 2. Redis確認とセッション削除

```shell
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"
```
セッション情報を削除

```shell
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]ボタンを押してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338832/ccc9cc61-c8ce-3c22-5644-36cd0c84f7f3.png)

**セッションを強制切断できました。**
残りの2アイテム

```shell
127.0.0.1:6379> keys *
1) "spring:session:sessions:expires:0b288446-d209-4ecc-bfc4-7adf405e68a7"
2) "spring:session:expirations:1604421420000"
```
についてはTTL(有効期限）が設定されているので、とりあえず放置でよいでしょう。