セッション管理

利用者を識別できる
Webアプリを作ろう!
~セッション管理~
学習目標

セッション管理をするWebアプリが作れる



セッションとは何かを理解する
クッキーの仕組みを理解する
ステートレス/ステートフルの違いを説明でき
る
奥様WEBを会員制にしよう

ログインしないと使えな
いようにする


ログインと
パスワード
を入力
おかしなレシピが投稿さ
れない
レシピを投稿するたびに
名前を入力しなくて良い
今回作るシステム

奥様WEB<画面遷移図>を参照
実際にはこんな感じです

デモを見てください
一人の人に対して
一連の流れでサービスを提供する
「永井」としてログインして投稿する

「今野君」としてログインして投稿する

・・・・
が
ログオン
投稿
永井
セッションといいます
今回作る奥様WEBはセッションを実現します!
セッションを実現するには?

奥様WEBを利用する
「ブラウザ」と
「Tomcat」との
「メッセージ(HTTPリクエスト・レスポンス)」の
「やりとり(TCP)」を
シミュレーションしてみよ
う!

役割分担



Tomcat役・ブラウザ役・TCP役:人
HTTPリクエスト・レスポンス役:紙
4人1組で組んでください
このような配役です
4人1組
ブラウザ1役
TCP役
ブラウザ2役
Tomcat役
注意点

TCP役の人
・ブラウザとTomcatの間で紙を受け渡します

Tomcat役の人
・他の3人に対し後ろ向きで立ってください
・一度もらったメッセージは伏せて置いてください
(見ちゃダメ)
シナリオ
①ブラウザ1がサーバにとの間にTCPコネクションを張る
②ブラウザ1がサーバにHTTPリクエストを送る
③サーバがHTTPレスポンスを返す
④TCPコネクションはHTTPの規則に従いさよなら
⑤ブラウザ2がサーバにとの間にTCPコネクションを張る
⑥ブラウザ2がサーバにHTTPリクエストを送る
⑦サーバがHTTPレスポンスを返す
⑧ブラウザ2がサーバにHTTPリクエストを送る
⑨ログオンした人しか投稿はできない・・・
このクライアントはログオンしている人なのか??
今のシミュレーションの問題点

誰からレシピ投稿があったか分からない
一回ずつ繋がりが切れる
このように、やりとりが1回1回切断されていて
独立した状態になることを
「ステートレス」といいます
ステートレスな通信の例:HTTP
% telnet web.sfc.keio.ac.jp 80
Trying 133.27.10.28...
Connected to web.sfc.keio.ac.jp.
Escape character is '^]'.
GET /~t99786mf/index.html
<HTML>
</HEAD>
<TITLE>MISATO'S WORLD!!!
</TITLE>
</HEAD>
<BODY>
・・・・・・・・・
</BODY>
</HTML>
Connection closed by foreign host.
%
赤文字:自分で入力
黒文字:ホストが出力
ステートレスでない通信の例:
SMTP
%telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
220 nautilus.crew.sfc.keio.ac.jp ESMTP
HELO
250 nautilus.crew.sfc.keio.ac.jp
MAIL FROM: 差出人メールアドレス
250 ok
RCPT TO: 宛先メールアドレス
250 ok
DATA
354 go ahead
(本文)
.
250 ok 1022650055 qp 17435
QUIT
221 nautilus.crew.sfc.keio.ac.jp
Connection closed by foreign host.
%
赤文字:自分で入力
黒文字:ホストが出力
明示的に切断要求
2つの例の比較
HTTP
切断までのリクエ リクエスト:1回
スト・レスポンスの レスポンス:1回
回数
切断方法
SMTP
リクエスト:5回
レスポンス:5回
サーバが強制的に クライアントが任意
切断
で切断要求
やり取りが1回1回切断されていて独立した状態になる
ことを「ステートレス」といいます

やり取りが1回1回切断されず連続した状態になること
を「ステートフル」といいます

ステートレスな通信で
セッションを実現する


今度はHTTPを擬似的にステートフルにな
るようにしてみましょう
シミュレーションをしてみよう


もう一度4人1組で組んでください
役割分担は同じです
シナリオ
①ブラウザ1がサーバにとの間にTCPコネクションを張る
②ブラウザ1がサーバにHTTPリクエストを送る
③サーバがCookie付きHTTPレスポンスを返す
④TCPコネクションはHTTPの規則に従いさよなら
⑤ブラウザ2がサーバにとの間にTCPコネクションを張る
⑥ブラウザ2がサーバにHTTPリクエストを送る
⑦サーバがCookie付きHTTPレスポンスを返す
⑧ブラウザ2がサーバにCookie付きHTTPリクエストを送る
⑨ログオンした人しか投稿はできないが、ログオンした証が
あるので投稿を受け付ける
Cookieを使ったセッションの実現

サーバがクライアントにHTTPレスポンスを
返す時にCookie(暗証番号)を加えて返す


サーバは暗証番号と他の情報(ユーザ名など)
をハッシュテーブルのようにして持っています
クライアントがCookie(暗証番号)と一緒に
HTTPリクエストを出す

受け取ったサーバは暗証番号によってどのクラ
イアントから来たHTTPリクエストか判別できる
暗証番号付きやりとり
サーバ
クライアント
ログオン画面
永井です
ログオンします
HTTPリクエスト
ログオン画面
暗証番号を生成
Servlet
AB
永井
暗証番号付きやりとり
サーバ
クライアント
“ログオン済”
ログオン画面
画面
Servlet
いいですよ!
暗証番号はABを
使ってください
Cookie=AB
AB
HTTPレスポンス
暗証番号をCookieに設定
ログオン画面
永井
暗証番号付きやりとり
サーバ
クライアント
投稿画面
Cookie=AB
ログオン画面
今野です
ログオンします
HTTPリクエスト
Servlet
AB
永井
CD
今野
暗証番号付きやりとり
サーバ
クライアント
Servlet
投稿画面
いいですよ!
暗証番号はCDを
使ってください
Cookie=AB
AB
永井
CD
今野
HTTPレスポンス
“ログオン済”
ログオン画面
画面
Cookie= CD
暗証番号付きやりとり
クライアント
投稿画面
Cookie=AB
投稿画面
Cookie=CD
レシピ投稿します
暗証番号はCDです
レシピ名=海鮮サラダ
作り方=①材料を手
でちぎる
・・・
HTTPリクエスト
サーバ
Servlet
AB
永井
CD
今野
暗証番号付きやりとり
サーバ
クライアント
Servlet
投稿画面
「暗証番号=CD」さん
ログオンしていますね
投稿受け付けました
Cookie=AB
AB
永井
CD
今野
HTTPレスポンス
“投稿済”
投稿画面
画面
Cookie=CD
サーブレットを書く

今日のサーブレット



LoginServlet.java
IchiranServlet.java
ToukouServlet.java
セッションオブジェクトの共有
Login
Servlet
Ichiran
Servlet
Toukou
Servlet
セッションオブジェクト

セッションオブジェクトはサーブレット間で共有されます

同じWebアプリ内ならセッションオブジェクトは共有される
LoginServlet.java: doPost()



ログイン情報の入力を受ける
ログイン認証をする
ログインしている状態にする


Sessionオブジェクトを生成する
ログインしたことを伝えるページを表示する
ログインとは

プログラム上ではどのような意味を持って
いますか


ここではセッションの無い状態からある状態に
変わること
セッションの扱い方をソースと照らし合わ
せてみましょう
ログインしている状態にする
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
・・・・・・・
//********ログインしている状態にする*********
43
//セッションオブジェクトを生成する
HttpSession session = request.getSession(true);
//セッションにユーザ名を入れる
session.setAttribute("name", name);
46
49
Sessionオブジェクトを生成
・・・・・・・
}
Cookie
(SessionID)
“AB”
Sessionオブジェクト
(セッション中に保持する情
報)
名前=永井
IchiranServlet.java: doGet()


閲覧者がログインしているか調べる
レシピ一覧を出力する
ログインしているか調べるには

ログインした時に何をしたか?


Sessionオブジェクトを生成した
Sessionオブジェクトがあるかどうかを調べ
よう
ログインしているか調べる
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
ログインチェック
//*****閲覧者がログインしているか調べる*****
HttpSession session = request.getSession(false);//セッションの取得
24
//ログインしていなかった場合、エラーページを生成する
if(session == null){
createErrorPage(response);
return;//ここで、メソッドを終了する
}
27
//*****レシピ一覧を出力する*****
・・・・・
}
Cookie
(SessionID)
“AB”
nullチェック
Sessionオブジェクト
(セッション中に保持する情
報)
名前=永井
ToukouServlet.java: doPost()


投稿者がログインしているかを調べる
レシピの投稿を受け付ける



Sessionからログインしたユーザ名を取り出す
受け付けたレシピをファイルに書き込む
感謝のメッセージのHTMLを出力する
Sessionからログインした
ユーザ名を取り出す
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
・・・・・・
セッションから情報を取得
//***** 投稿者がログインしているかを調べる *****
HttpSession session = request.getSession(false);//セッションを取得
23
34
}
//***** レシピの投稿を受け付ける *****
//セッションとHTTPリクエストのパラメータから、レシピを構成する情報を取り出す
String contributor = (String)session.getAttribute("name");//セッションからログイン
したユーザ名を取り出し、それを投稿者とする
String title = request.getParameter("title"); //タイトル
Sessionオブジェクト
String content = request.getParameter("content");
Cookie //レシピ内容
(セッション中に保持する情
(SessionID)
報)
・・・・・・
名前=永井
“AB”
タイムアウトに関して

なぜタイムアウトをする必要があるのか?


Cookie(暗証番号)が盗まれたらどうなるか


タイムアウトが無ければいつでもログインせずにWeb
アプリが使えるのに・・・
例)クレジットカードを使う買い物サイトで・・・
自分の情報を勝手に使われてしまうかもしれな
い

泥棒よけ
今日の課題です


配られたソースを元に動かしてください
奥様WEBにログアウト機能をつけてください

セッションを消す(終了)するには
HttpSessionのinvalidateメソッドを実行
session.invalidate();

数字が増えるサーブレットを作ってください

IE2枚でそれぞれが別の流れで数字が増える仕様に
してください