Spring BootでセッションIDがアドレスバーに表示される理由と対策|新人エンジニア向けにJSESSIONIDを解説

こんにちは。ゆうせいです。

今回は、Spring BootでセッションIDがアドレスバーに表示される理由と、その対策を新人エンジニア向けに解説します。

Webアプリケーションを開発していると、URLに次のような文字列が付くことがあります。





または、画面遷移したときに次のように見えることがあります。

/login;jsessionid=F1A2B3C4D5E6
/mypage;jsessionid=F1A2B3C4D5E6

この;jsessionid=...が、セッションIDです。

結論から言うと、セッションIDがアドレスバーに表示される主な理由は、サーバーがCookieではなくURLでセッションを追跡しようとしているからです。

この仕組みはURL rewriting、つまりURL書き換えと呼ばれます。

ServletのHttpServletResponseにはencodeURLという仕組みがあり、必要な場合にはURLへセッションIDを含めてエンコードします。Jakarta Servlet APIのJavadocでも、encodeURLはセッションIDを含めることで指定されたURLをエンコードし、Cookieをサポートするブラウザやセッショントラッキングが無効な場合にはURL変更が不要になると説明されています。

セッションIDとは何か

まず、セッションIDとは何かを確認しましょう。

セッションとは、サーバー側でユーザーごとの状態を覚えておく仕組みです。

たとえば、ログイン中のユーザー情報、カートの中身、一時的な入力情報などを管理するときに使います。

HTTP通信は、本来「前のリクエストを覚えていない」仕組みです。

そのため、サーバーは「このリクエストは、さっきログインした山田さんの続きだ」と判断するための目印が必要になります。

その目印がセッションIDです。

たとえるなら、セッションIDはテーマパークの再入場スタンプのようなものです。

スタンプがあれば、スタッフは「この人はすでに入場済みだ」と判断できます。

Webアプリでは、そのスタンプの役割をセッションIDが担います。

通常はCookieでセッションIDを管理する

通常、Spring BootのWebアプリケーションでは、セッションIDはCookieで管理されます。

Cookieとは、ブラウザに保存される小さなデータです。

Spring BootやServletコンテナでは、よくJSESSIONIDという名前のCookieが使われます。

Cookie: JSESSIONID=ABC123DEF456





この場合、URLにはセッションIDが出ません。

ブラウザが裏側でCookieをサーバーへ送ってくれるためです。

ブラウザ
        ↓ Cookie: JSESSIONID=ABC123
Spring Boot
        ↓
同じユーザーのセッションだと判断する




つまり、理想的にはセッションIDはアドレスバーではなくCookieに入っている状態です。

なぜURLにjsessionidが出るのか

セッションIDがURLに出るのは、サーバーが「CookieでセッションIDを渡せないかもしれない」と判断したときです。

代表的な原因は次のとおりです。

原因説明
ブラウザでCookieが無効Cookieを保存できないため、URLでセッションIDを渡そうとする
URL追跡モードが有効セッション追跡方法としてURL rewritingが使える状態になっている
初回アクセス時Cookieがまだ確実に返ってきていないため、環境によってURLに付くことがある
Secure Cookieの設定ミスHTTP環境なのにSecure属性を付け、Cookieが送信されない
プロキシやロードバランサーの設定問題Set-Cookieヘッダーが消える、ドメインやパスが合わないなど
手動でURLに付けているコードやテンプレートでセッションID付きURLを生成している

新人エンジニア向けに一言で言うと、Cookieで渡せないときの代替手段として、URLにセッションIDが付くことがあります。

荷物の受け渡しでたとえるなら、本来は封筒の中に会員証を入れて渡したいのに、封筒が使えないため、会員番号を荷物の外側に大きく書いてしまっているような状態です。

外側に書けば相手には届きます。

しかし、周囲の人にも見えてしまいますよね。

URL rewritingとは何か

URL rewritingとは、URLの中にセッションIDを埋め込んで、セッションを追跡する方法です。

/mypage;jsessionid=ABC123DEF456




この場合、ブラウザがCookieを送れなくても、サーバーはURLに含まれるjsessionidを見て、どのセッションか判断できます。

Spring BootのSessionTrackingModeにも、COOKIE、URL、SSLという追跡モードがあります。Spring Boot APIのJavadocでは、COOKIEはCookieでセッションを追跡し、URLはURLを書き換えてセッションIDを追加するモードだと説明されています。

追跡方法説明実務でのおすすめ
COOKIECookieでJSESSIONIDを管理する基本はこちら
URLURLにjsessionidを付ける避けたい
SSLSSLの仕組みで追跡する一般的にはあまり使わない

現代のWebアプリケーションでは、基本的にCookieでセッション管理する設計が自然です。

URLにセッションIDを出す設計は、セキュリティ面で避けたほうがよいです。

URLにセッションIDが出るとなぜ危険なのか

URLにセッションIDが出ると、次のようなリスクがあります。

リスク説明
ブラウザ履歴に残るセッションID付きURLが履歴に保存される
ブックマークされる古いセッションID付きURLを保存してしまう
ログに残るアクセスログやプロキシログにセッションIDが残る
共有されるURLをチャットやメールで送るとセッションIDも渡る
Refererで漏れる外部サイトへ遷移したときにURLが伝わる可能性がある
セッション固定攻撃の入口になる攻撃者が用意したセッションIDを使わせるリスクがある

Spring Securityの公式ドキュメントでも、攻撃者がセッションIDを含むリンクをユーザーへ送って同じセッションでログインさせるようなセッション固定攻撃がリスクとして説明されています。Spring Securityはログイン時に新しいセッションを作成したりセッションIDを変更したりすることで、セッション固定攻撃から自動的に保護します。

Spring Securityが対策してくれる部分はあります。

しかし、だからといってURLにセッションIDを出してよいわけではありません。

セッションIDは、ログイン状態を識別する大切な鍵です。

鍵を玄関マットの下に置くより、ポケットの中にしまうほうが安全ですよね。

Cookieはポケット。

URLは外から見える札。

そのくらいの違いがあります。

まず確認すべきこと

セッションIDがURLに出たら、まず次の順番で確認してください。

1. ブラウザでCookieが有効か確認する
2. DevToolsでJSESSIONID Cookieが保存されているか確認する
3. application.propertiesのsession設定を確認する
4. Secure CookieをHTTP環境で使っていないか確認する
5. リダイレクトやリンク生成でjsessionidが付いていないか確認する
6. プロキシやロードバランサーでSet-Cookieが消えていないか確認する




いきなりControllerやServiceを疑う前に、Cookieとセッション追跡モードを確認しましょう。

DevToolsでCookieを確認する

ChromeやEdgeのDevToolsで確認できます。

1. F12でDevToolsを開く
2. Applicationタブを開く
3. Cookiesを開く
4. http://localhost:8080 を選ぶ
5. JSESSIONIDがあるか確認する




Networkタブでも確認できます。

1. Networkタブを開く
2. 画面を再読み込みする
3. 対象リクエストをクリックする
4. Response Headersを見る
5. Set-Cookie: JSESSIONID=... があるか確認する
6. Request Headersを見る
7. Cookie: JSESSIONID=... が送られているか確認する




確認ポイントは2つです。

見る場所確認内容意味
Response HeadersSet-CookieがあるかサーバーがCookieを発行しているか
Request HeadersCookieが送られているかブラウザがCookieを返しているか

Set-Cookieはあるのに次のリクエストでCookieが送られていない場合、ブラウザ側のCookie設定、Secure属性、SameSite、ドメイン、パスなどを疑います。

対策1:セッション追跡をCookieのみにする

もっとも重要な対策は、セッション追跡をCookieのみに制限することです。

application.propertiesに次の設定を追加します。

server.servlet.session.tracking-modes=cookie




Spring Bootの共通アプリケーションプロパティには、server.servlet.session.tracking-modesがセッション追跡モードを設定するプロパティとして掲載されています。

この設定により、URL rewritingではなくCookieでセッションを追跡する方針にできます。

application.ymlで書く場合は、次のようになります。

server:
  servlet:
    session:
      tracking-modes: cookie




新人エンジニアは、まずこの設定を覚えてください。

server.servlet.session.tracking-modes=cookie

URLにjsessionidを出したくない場合の基本対策です。

対策2:Java設定でCookieのみにする

application.propertiesではなく、Javaの設定クラスで制御することもできます。

package com.example.demo.config;

import jakarta.servlet.SessionTrackingMode;
import java.util.Set;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SessionConfig {

    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
            servletContext.setSessionTrackingModes(
                    Set.of(SessionTrackingMode.COOKIE)
            );
        };
    }
}




このコードでは、ServletContextに対してセッション追跡モードをCOOKIEだけに設定しています。

基本的にはapplication.propertiesのほうが簡単です。

ただし、細かい条件で設定したい場合や、プロファイルごとにJavaで制御したい場合は、このような設定も使えます。

方法向いている場面
application.propertiesシンプルに設定したい
Java設定クラスコードで細かく制御したい

対策3:CookieのHttpOnlyを有効にする

セッションIDをCookieで管理する場合、Cookieの安全性も大切です。

まず、HttpOnlyを有効にします。

server.servlet.session.cookie.http-only=true




Spring Bootの共通アプリケーションプロパティでは、server.servlet.session.cookie.http-onlyはCookieにHttpOnlyを使うかどうかの設定として説明されています。

HttpOnlyとは、JavaScriptからCookieを読み取れないようにする属性です。

たとえば、悪意あるJavaScriptがページに埋め込まれた場合でも、document.cookieでJSESSIONIDを盗みにくくできます。

ただし、HttpOnlyは万能ではありません。

XSSそのものを防ぐわけではありません。

あくまで、CookieをJavaScriptから読み取りにくくする防御策です。

対策4:本番環境ではSecureを使う

HTTPSで動かす本番環境では、Secure属性も検討します。

server.servlet.session.cookie.secure=true




Spring Bootの共通アプリケーションプロパティでは、server.servlet.session.cookie.secureはCookieを常にSecureとしてマークするかどうかの設定として説明されています。

Secure属性が付いたCookieは、HTTPS通信のときだけ送信されます。

本番環境では安全性を高められます。

ただし、開発環境でhttp://localhost:8080を使っているのにSecure=trueにすると、ブラウザがCookieを送らないことがあります。

その結果、ログインが維持されなかったり、セッションIDがURLに出たりする原因になる場合があります。

環境Secure設定注意点
ローカルHTTPfalseまたは未設定Secure=trueだとCookieが送られないことがある
本番HTTPStrueHTTPSでのみCookieを送る

Secureは本番向けには重要です。

しかし、HTTPの研修環境やローカル環境では設定ミスの原因にもなります。

環境ごとに設定を分けましょう。

application-dev.propertiesとapplication-prod.propertiesで分ける

開発環境と本番環境で設定を分ける例です。

application-dev.propertiesです。

server.servlet.session.tracking-modes=cookie
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=false
server.servlet.session.cookie.same-site=lax




application-prod.propertiesです。

server.servlet.session.tracking-modes=cookie
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
server.servlet.session.cookie.same-site=lax




Spring Bootの共通アプリケーションプロパティには、server.servlet.session.cookie.same-siteもCookieのSameSite設定として掲載されています。

SameSiteは、別サイトからのリクエストでCookieを送るかどうかに関わる設定です。

CSRF対策とも関係します。

研修段階では、まずHttpOnly、Secure、SameSiteという名前を知っておくとよいです。

対策5:URLを手動で作っていないか確認する

URLにjsessionidが出る場合、Spring BootやServletコンテナだけでなく、自分のコードが原因のこともあります。

たとえば、セッションIDを自分でURLに入れているコードです。

悪い例です。

String url = "/mypage;jsessionid=" + session.getId();

このように手動でセッションIDをURLへ付けるのは避けてください。

HTMLやThymeleafでも、セッションIDをhiddenやリンクに入れる設計は避けましょう。

悪い例です。

<a th:href="@{'/mypage;jsessionid=' + ${sessionId}}">マイページ</a>

良い例です。

<a th:href="@{/mypage}">マイページ</a>

セッション管理は、基本的にServletコンテナやSpring Securityに任せます。

新人エンジニアが手動でセッションIDをURLへ埋め込む必要は、通常ありません。

対策6:不要なセッション作成を減らす

セッションIDが出るということは、どこかでセッションが作られている可能性があります。

次のようなコードを書くと、セッションが作られることがあります。

@GetMapping("/sample")
public String sample(HttpSession session) {
    session.setAttribute("message", "こんにちは");
    return "sample";
}




また、次のようにrequest.getSession()を呼ぶと、セッションが作られることがあります。

HttpSession session = request.getSession();




もし「本当にセッションが必要なのか」を確認したい場合は、request.getSession(false)を使うと、既存セッションがある場合だけ取得できます。

HttpSession session = request.getSession(false);

if (session == null) {
    System.out.println("まだセッションは作られていません。");
}




セッションは便利です。

しかし、何でもかんでもセッションに入れると、状態管理が複雑になります。

ログイン情報、カート、一時的に必要な情報など、必要な場面に絞って使いましょう。

Spring Securityを使っている場合

Spring Securityを使っている場合、ログインや認証情報の保持にセッションが使われることがあります。

Spring Securityの公式ドキュメントでは、Spring SecurityはデフォルトでセキュリティコンテキストをHTTPセッションに保存すると説明されています。

つまり、ログイン機能があるアプリでは、セッションそのものが使われるのは自然です。

問題は、セッションを使うことではありません。

セッションIDがURLに出ることです。

ログイン機能がある場合でも、セッションIDはCookieで管理するように設定しましょう。

server.servlet.session.tracking-modes=cookie
server.servlet.session.cookie.http-only=true




さらに、本番HTTPS環境では次も検討します。

server.servlet.session.cookie.secure=true
server.servlet.session.cookie.same-site=lax




ログアウト後に古いJSESSIONIDが残る場合

ログアウト後にブラウザ側へJSESSIONID Cookieが残っているように見えることがあります。

Spring Securityやアプリ側のログアウト処理でセッションを無効化しても、ブラウザ表示やプロキシ構成によって混乱することがあります。

Spring Security公式ドキュメントでは、プロキシ配下でアプリケーションを動かしている場合、Apache HTTPDのmod_headersを使ってログアウトリクエストのレスポンスでJSESSIONID Cookieを期限切れにする例も示されています。

ただし、新人研修や通常のSpring Boot学習では、まず次を確認してください。

セッションをinvalidateしているか
Spring Securityのlogout設定があるか
Set-CookieでJSESSIONIDが削除または更新されているか
ブラウザのCookieが残っていないか
URLに古いjsessionidが残っていないか




ログアウト後の挙動は、Cookie、セッション、Spring Security、ブラウザキャッシュが絡むため、DevToolsで確認するのが大切です。

セッションIDがURLに出たときのチェックリスト

確認項目見る場所対策
Cookieが無効になっていないかブラウザ設定Cookieを有効にする
JSESSIONID Cookieが保存されているかDevTools ApplicationSet-CookieとCookie送信を確認する
URL追跡が有効になっていないかapplication.propertiestracking-modes=cookieにする
HTTPなのにSecure=trueではないかapplication.propertiesローカルではsecure=falseにする
手動でjsessionidをURLに付けていないかController、HTML、ThymeleafセッションIDをURLに出さない
プロキシでCookieが消えていないかNetwork、プロキシ設定Set-Cookieヘッダーを確認する
古いURLを踏んでいないかブラウザ履歴、ブックマークjsessionidなしのURLから入り直す

おすすめの基本設定

Spring Bootの画面アプリで、セッションIDをURLに出したくない場合の基本設定です。

server.servlet.session.tracking-modes=cookie
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.same-site=lax




本番がHTTPSなら、次も追加します。

server.servlet.session.cookie.secure=true




ローカル開発がHTTPなら、次のようにします。

server.servlet.session.cookie.secure=false




環境ごとの使い分けが重要です。

設定意味
tracking-modes=cookieセッション追跡をCookieに限定する
http-only=trueJavaScriptからCookieを読み取りにくくする
same-site=lax別サイトからのCookie送信をある程度制限する
secure=trueHTTPSでのみCookieを送る

新人エンジニアがやりがちな誤解

誤解1:URLに出ているからSpring Bootのバグだと思う

URLにjsessionidが出るのは、Spring Bootのバグとは限りません。

Cookieが使えない、URL追跡が有効、Secure属性の設定ミスなど、セッション追跡の仕組みとして起きることがあります。

誤解2:セッションを使うこと自体が悪いと思う

セッションを使うこと自体は悪くありません。

ログイン状態やカート情報など、サーバー側で状態を管理したい場面ではよく使います。

問題は、セッションIDがURLに露出することです。

誤解3:Cookieを使えば何でも安全だと思う

Cookieに入れれば絶対に安全、というわけではありません。

HttpOnly、Secure、SameSite、HTTPS、XSS対策、CSRF対策なども必要です。

Cookieは鍵を入れるポケットですが、ポケットに穴が空いていたら危険ですよね。

Cookieにも守り方があります。

誤解4:JavaScriptでJSESSIONIDを読む必要があると思う

通常、JavaScriptでJSESSIONIDを読む必要はありません。

ログインユーザー名を表示したいなら、Cookieから直接読むのではなく、ControllerのModel、Thymeleaf、またはユーザー情報APIを使います。

セッションIDは、画面表示用のデータではありません。

サーバーとブラウザの間で状態を識別するための裏方情報です。

安全なログイン画面の考え方

ログイン機能があるアプリでは、次の方針を意識してください。

セッションIDはCookieで管理する
URLには出さない
ログにも出さない
画面にも出さない
JavaScriptでも読まない
ログイン後はセッションIDを変更する
HTTPSで通信する

Spring Securityを使っている場合、セッション固定攻撃への保護としてログイン時にセッションIDを変更する仕組みが用意されています。Servlet 3.1以降の環境ではchangeSessionIdがデフォルトのセッション固定保護として説明されています。

それでも、URLにセッションIDが出る設計は避けるべきです。

セッションIDは秘密に近い情報として扱いましょう。

まとめ

Spring BootでセッションIDがアドレスバーに表示される主な理由は、CookieではなくURL rewritingでセッションを追跡しているからです。

URLに表示されるセッションIDは、;jsessionid=...という形で出ることが多いです。

ServletのencodeURLは、必要な場合にURLへセッションIDを含める仕組みを持っています。

ポイント内容
セッションIDユーザーのセッションを識別するためのID
JSESSIONIDServlet系アプリでよく使われるセッションCookie名
URL rewritingURLにセッションIDを埋め込む方式
原因Cookie無効、URL追跡有効、Secure設定ミスなど
基本対策server.servlet.session.tracking-modes=cookie
Cookie保護HttpOnly、Secure、SameSiteを設定する
確認方法DevToolsでSet-CookieとCookie送信を確認する

一言でまとめるなら、セッションIDがアドレスバーに出るのは「Cookieで管理したい情報がURLへ出てしまっている状態」です。

今後の学習では、HTTPセッション、JSESSIONID、Cookie、URL rewriting、HttpOnly、Secure、SameSite、Spring Securityのセッション固定攻撃対策、DevToolsでのCookie確認を順番に学ぶとよいです。まずはDevToolsでJSESSIONIDがCookieとして保存されているかを確認し、URLに;jsessionidが出ない状態を作ってみましょう!

セイ・コンサルティング・グループでは新人エンジニア研修のアシスタント講師を募集しています。

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。

学生時代は趣味と実益を兼ねてリゾートバイトにいそしむ。長野県白馬村に始まり、志賀高原でのスキーインストラクター、沖縄石垣島、北海道トマム。高じてオーストラリアのゴールドコーストでツアーガイドなど。現在は野菜作りにはまっている。