【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());
}