SpringBootにおけるcookie使用有無のセッション情報の管理についてご紹介します。
目次
条件
- Spring Boot(Spring Tool Suiteで動作)
- maven
- thymeleaf
セッション情報の保持について
セッション情報は通常、クライアントのブラウザとcookieを送受信することによって管理されます。
しかし、cookieを使用できないブラウザについては、
URLパラメータにセッション情報を付加することでセッション管理を行う方法もあります。
(この方法は、セッションハイジャックなどのリスクが高まるため非推奨です。)
Spring Bootにおけるセッション管理
簡単なプログラムを用いて、Spring Bootにおけるセッション管理の動作を確認してみます。
ここでは以下のようなプロジェクト構成としました。
ソース等
SampleController.java
以下のURLにアクセスすると、入力フォームを表示します。
http://localhost:8080/first
入力フォームから値が送信されたら、
「/recieve」で受信し受け取ったデータをセッションに保存します。
その後、http://localhost:8080/secondへリダイレクトします。
http://localhost:8080/second では、
入力フォームで入力した文字列をセッションから取り出します。
package com.example.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class SampleCotroller { private final String strAttribute = "inputString"; @GetMapping("/first") public String first() { return "first"; } @GetMapping("/second") public String second(HttpServletRequest request) { // セッションの取得 HttpSession session = request.getSession(); String inputString = (String) session.getAttribute(strAttribute); System.out.println("inputString = " + inputString); return "second"; } @PostMapping("/recieve") public String recieve(@RequestParam String message, HttpServletRequest request, HttpServletResponse response) { // セッションの取得 HttpSession session = request.getSession(); // セッションに情報を保持 session.setAttribute(strAttribute, message); return "redirect:/second"; } }
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.6</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>sessionTest</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sessionTest</name> <description>Example Project</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
first.html
入力フォームだけの単純な画面です。
<html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>form</title> <script type="text/javascript"></script> </head> <body> <form th:action="@{/recieve}" method="post"> <label> メッセージ:<input type="text" name="message"><br> </label> <button>送信</button> </form> </body> </html>
second.html
「セッションID」と「フォームで入力した文字列(セッションから取得)」を表示する画面です。
<html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>form</title> <script type="text/javascript"></script> </head> <body> <h3>Session Id</h3> <p th:text="${#httpSession.id}"/> <h3>InputString</h3> <p th:text="${#httpSession.getAttribute('inputString')}"/> <input type="button" onclick="window.history.back();" value="直前のページに戻る"> </body> </html>
ブラウザ(Chrome)を右クリック > 検証 で確認したところ、
cookieによってセッション情報のやり取りが行われていることが分かります。
ブラウザの設定でcookieを使用不可にします。
URLに「;jsessionid=59CA475E0CC821E479B13F32D28054FB」という値が付加されました。
イコールの後ろの文字列はセッションIDです。
cookieもブラウザ上で確認出来ますが、Value値が異なっています。
これは、前回使用したcookieがただ残っているだけであると分かります。
つまり、ブラウザがcookieを受け入れない設定になったため、
自動でURLにセッションIDを付加する動作に変わったということです。
自動でセッションIDをURLに付加したくない場合
ブラウザのcookie使用可否に応じて、自動でセッション情報のやり取り方法を変えてくれるのは便利です。
しかし、セキュリティ上の問題から、セッションIDをURLに付加したくないケースもあるかと思います。
その場合、以下のようなソースを追加することで実現可能です。
MyConfig.java
package com.example; import java.util.Collections; import javax.servlet.SessionTrackingMode; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MyConfig { @Bean public ServletContextInitializer servletContextInitializer() { ServletContextInitializer initializer = servletContext -> { servletContext .setSessionTrackingModes(Collections.singleton(SessionTrackingMode.COOKIE)); }; return initializer; } }
URLにセッション情報が付加されていないことがわかります。
ただし、セッション情報が使用できなくなり、InputStringが表示されていないことが分かります。
ブラウザのcookieが有効であれば、問題なくセッション情報を使用することが出来ます。