目的
セッション情報をMySQLに保存する。
前提条件
SpringSecurityでJDBC認証を実装していること。
この記事まで進めた状態
依存関係の設定
公式ドキュメントに沿って次の依存関係を追加する。
org.springframework.session:spring-session-jdbc
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
今回はSpringBootのAutoConfigが有効なので@EnableJdbcHttpSession
のアノテーションは不要。
セッションストレージ用のテーブル
デフォルトではSPRING_SESSION
、SPRING_SESSION_ATTRIBUTES
という名前のテーブルを使用するようになっている。
今回はDBにMySQLを使用しているため次のスキーマを使用する。
使用するDBによって適宜変更する。migrationにDDLを追加する。(今回は-- V0.03__create_session_tables.sql
としてまとめて追加)
シリアライズ
migrationに成功していると起動時に次のようなログが表示され、SPRING_SESSION
,SPRING_SESSION_ATTRIBUTES
のテーブルが生成される。
2025-07-06T01:44:48.056+09:00 INFO 97753 --- [demo] [ restartedMain] o.f.core.internal.command.DbMigrate : Migrating schema `mydatabase` to version "0.03 - create session tables"
ここまでの状態でログイン画面からログインするとTomcatのエラー画面が表示される。
エラーメッセージの内容の一部に次のメッセージが表示されている。
java.io.NotSerializableException: com.example.demo.entity.AppUser
結論を述べるとAppUserクラスはSerializableインターフェースを実装していなければならないということである。
そのためこのようにSerializableをAppUserに実装すればエラー画面は表示されなくなる。
public class AppUser extends User implements Serializable {
ログインすると次のようなレコードが生成されている。
SPRING_SESSIONテーブル
PRIMARY_ID | SESSION_ID | CREATION_TIME | LAST_ACCESS_TIME | MAX_INACTIVE_INTERVAL | EXPIRY_TIME | PRINCIPAL_NAME |
---|---|---|---|---|---|---|
8c0cd656-31b0-47bb-a495-692a678adf43 | 83244247-4ff9-4aa2-991b-9e7943c99846 | 1751787357961 | 1751787961465 | 1800 | 1751789761465 | test_user1 |
SPRING_SESSION_ATTRIBUTESテーブル
SESSION_PRIMARY_ID | ATTRIBUTE_NAME | ATTRIBUTE_BYTES |
---|---|---|
8c0cd656-31b0-47bb-a495-692a678adf43 | SPRING_SECURITY_CONTEXT | 0xACED00057372003D6F72677... |
ATTRIBUTE_BYTESのカラムにバイトコード変換されたセッション情報が格納されている。
このように変換するためにSerializableインターフェースを使用している。
Serializableはサーバーの外部にインスタンスの書き込みを行う場合などに主に使用することが多い。
Tomcatのアプリケーションサーバー内にセッション情報を保持する場合であればSerializableは不要だが今回はアプリケーションサーバー外のDBに永続化しているため必要となる。
セッションの有効期間を変更する
30mから60mに変更すると確かにMAX_INACTIVE_INTERVALのカラムが更新されている。
server:
servlet:
session:
timeout: 60m
PRIMARY_ID | SESSION_ID | CREATION_TIME | LAST_ACCESS_TIME | MAX_INACTIVE_INTERVAL | EXPIRY_TIME | PRINCIPAL_NAME |
---|---|---|---|---|---|---|
81764455-6c19-40af-b558-1665b8a22865 | 180b7d94-3202-424f-a787-e859523cf446 | 1751791440406 | 1751791445239 | 3600 | 1751795045239 | test_user1 |
EnableJdbcHttpSessionのアノテーションを使用するとセッションの有効期限が30mに固定される。application.ymlでセッションの有効期限を設定していたとしてもこのアノテーションの有効期限が優先され30mで固定されるため注意。
参考