【Spring Boot】セッションとCookie
セッション
Spring Boot でセッションと取り扱う方法はいくつかあります。
セッションの取り扱いについて、Controller
とRestController
に違いはありません。
RESTful API の場合、ステートレスの観点からセッションを使用することはありません。 しかし、SPA などの実装の都合上、どうしてもセッションを使った方がよいケースがあります。
HttpSession
通常の Servlet で使用するHttpSession
を使用します。
HttpSession
は DI コンテナから参照します。
セッションを再生成する場合は、破棄してからHttpServletRequest
のgetSession()
を使用します。
@RestController
public class SampleController {
@Autowired
private HttpSession session;
@GetMapping
public Object getData() {
//セッションデータ取得
return session.getAttribute("data");
}
@PostMapping
public void setData(@RequestBody SampleData data, HttpServletRequest request) {
//セッション再生成
session.invalidate();
session = request.getSession()
//セッションデータ設定
session.setAttribute("data", data);
}
}
@SessionScope
以下のように@SessionScope
を設定した Bean を作成します。
これにより DI のスコープがセッションに設定されます。
@Component
@SessionScope
public class SessionData implements Serializable {
private static final long serialVersionUID = 808198990406616280L;
private SampleData sampleData;
//コンストラクター・ゲッター・セッターは省略
}
@RestController
public class SampleController {
@Autowired
private SessionData sessionData;
@GetMapping
public SampleData getData() {
//セッションデータ取得
return sessionData.getSampleData();
}
@PostMapping
public void setData(@RequestBody SampleData data) {
//セッションデータ設定
sessionData.setSampleData(data);
}
}
上記の場合、セッションにはscopedTarget.sessionData
という名前で登録されます。
@SessionScope
は以下の@Scope
の設定と同義です。
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
@SessionAttributes
Controller ごとにセッションで使用するオブジェクトを@SessionAttributes
で指定します。
@RestController
@SessionAttributes(types = SampleData.class)
public class SampleController {
@ModelAttribute("sampleData")
private SampleData setSampleData() {
return new SampleData();
}
@GetMapping
public SampleData getData(@ModelAttribute SampleData sampleData) {
//セッションデータ取得
return sampleData;
}
@PostMapping
public void setData(@RequestBody SampleData data, @ModelAttribute SampleData sampleData) {
//セッションデータ設定(ディープコピー)
sampleData.clone(data);
}
}
@ModelAttribute("sampleData")
のメソッドによって、コントローラーアクセス時にsampleData
という名前でオブジェクトをセッションに登録します。
登録したオブジェクトは、@ModelAttribute
を付与したパラメーターによって参照することができます。
複数のオブジェクトを使用したい場合も考え方は基本同じです。
@RestController
@SessionAttributes(types = {SampleData.class, SampleData2.class})
public class SampleController {
@ModelAttribute("sampleData")
private SampleData setSampleData() {
return new SampleData();
}
@ModelAttribute("sampleData2")
private SampleData2 setSampleData2() {
return new SampleData2();
}
@GetMapping
public SampleData getData(@ModelAttribute SampleData sampleData) {
return sampleData;
}
@GetMapping
public SampleData2 getData2(@ModelAttribute SampleData2 sampleData) {
return sampleData2;
}
}
プロパティ
セッションについて、application.yml
(.properties
)に以下のプロパティが用意されています。
プロパティ | デフォルト | 説明 |
---|---|---|
server.servlet.session.persistent | false | 再起動時にセッションを保持するか |
server.servlet.session.store-dir | セッションの保存先フォルダ | |
server.servlet.session.timeout | 30m | セッションタイムアウトの時間 |
server.servlet.session.tracking-modes | セッション追跡モード | |
server.servlet.session.cookie.name | JSESSIONID | セッション Cookie 名 |
server.servlet.session.cookie.http-only | true | セッション Cookie の HttpOnly 設定 |
server.servlet.session.cookie.secure | false | セッション Cookie の Secure 設定 |
server.servlet.session.cookie.max-age | セッション Cookie の Max-Age 設定 | |
server.servlet.session.cookie.domain | セッション Cookie の Domain 設定 | |
server.servlet.session.cookie.path | セッション Cookie の Path 設定 | |
server.servlet.session.cookie.comment | セッション Cookie のコメント |
Cookie
Cookie についてはこちらの記事を参考にしてください。
設定
Cookie を設定するには、Cookie
オブジェクトを作成してレスポンスボディに追加します。
Cookie
オブジェクトの生成には、キーと値のセットを指定します。
@PostMapping
public void setCookie(HttpServletResponse response) {
Cookie cookie = new Cookie("key", "value");
response.addCookie(cookie);
}
各属性の設定は、Cookie
の以下のメソッドによって行います。
属性 | メソッド | 型 |
---|---|---|
Http-Only | setHttpOnly() | boolean |
Secure | setSecure() | boolean |
Max-Age | setMaxAge() | int |
Domain | setDomain() | String |
Path | setPath() | String |
Comment | setComment() | String |
取得
Cookie を取得するには、@CookieValue
を付与したパラメーターを指定します。
@GetMapping
public String getCookie(@CookieValue(name="key", required=false, defaultValue="none") String value) {
return value;
}
@CookieValue
には以下のプロパティがあります。
プロパティ | 説明 |
---|---|
name | 取得する Cookie の名前 |
required | true の場合、Cookie が存在しなければMissingRequestCookieException をスローする |
defaultValue | required がfalse で、Cookie が存在しない場合の代わりの値 |
SameSite について
Cookie
には SameSite の設定がありません。
SameSite の設定が必要な場合は、ResponseCookie
を使用します。
以下のように、ResponseCookie
はSet-Cookie
に設定する文字列を生成するためのジェネレーターです。
@PostMapping
public void setCookie(HttpServletResponse response) {
ResponseCookie cookie = ResponseCookie.from("key", "set")
.httpOnly(true)
.secure(false)
.sameSite(SameSite.LAX.attribute())
.build();
response.addHeader("Set-Cookie", cookie.toString());
}