利用者を識別するWebアプリ を作ろう! 2004年6月10日 武田林太郎
今日の目標 Webアプリでセッション管理を利用できるようになる ステートレスとステートフルについて説明できるようになる セッションとは何かを説明できるようになる サーブレットによるセッション管理ができるようになる
今日の内容 題材:「サブゼミ疑問解決掲示板~会員版~」 実習: 掲示板にセッション管理を使った機能を追加する
「サブゼミ疑問解決掲示板」って何だっけ? コンセプト 授業外で生じた疑問をみんなで共有・解決し 授業の理解を深めて、よりよいサブゼミにする ユーザができること 投稿する(投稿する疑問を解決したい) 授業外で生じた疑問を質問として掲示板に投稿。 投稿者の疑問を解決できると思う人が回答を投稿する。 閲覧する(質問と回答をみんなで共有して理解を深めたい)
今週の追加要求 投稿項目で同じものを,毎回入力するのは面倒なので,どうにかして欲しい 研究会以外の人が投稿できないようにして欲しい
要求その1 「連続投稿するとき何度も同じ情報を入力するのは面倒くさい.」 入室してからは,「タイトル」と「内容」だけを入力したい
要求その2 「おかしな投稿がされないために、研究会の人だけ使えるようにしてほしい。」 →会員制(ログインする)
今回の仕様 トップ画面で入力したパスワード(全員共通)でログイン認証できた人だけが利用できる トップ画面でユーザの情報も入力してもらう。 Webアプリ利用中は再びユーザの情報を入力することはない。
画面遷移 IchiranServlet LoginServlet ToukouServlet ※エラーページ割愛 トップ画面 投稿画面 一覧閲覧画面 IchiranServlet LoginServlet ToukouServlet →デモ
要求を満たすためには 「投稿項目で同じものを,毎回入力するのは面倒」に対してはどう解決したら良いでしょうか?
今日のWebアプリは “利用者を識別する”必要がある ユーザ:杉浦君がログインすると… Webアプリはユーザを杉浦君としてサービスを提供してくれる 投稿時に杉浦君のユーザ情報を付加してくれる ログイン済みのユーザと見てなす ユーザ:武田君がログインすると… Webアプリはユーザに武田君としてのサービスをしてくれる
利用者を識別するための問題点(1) 問)HTTPの特徴って何だっけ? ●クライアント(ブラウザ)とサーバとのやり取り(データ交換)は… と とで成り立つ。 ●1回やり取りした後に 接続は 維持・切断 される。 リクエスト レスポンス GETメソッドとPOSTメソッドがあった。
利用者を識別するための問題点(2) ●リクエスト/レスポンスごとに接続と切断が繰り返される。 Webサーバ 接続 (ブラウザ) リクエスト クライアント 接続 Webサーバ (ブラウザ) リクエスト レスポンス ●HTTPでは、 今回のリクエストと前のリクエスト/レスポンスとの関連がない.やりとりが1回1回切断されていて、独立していることを.ステートレスと言う. 定義
このままだとサーバは,ログインした杉浦君が2度目にリクエストしても、杉浦君だと特定できない。 利用者を識別するための問題点(3) このままだとサーバは,ログインした杉浦君が2度目にリクエストしても、杉浦君だと特定できない。 もうちょっと説明!!! ステートフル定義
解決編(1) 利用者を識別するためには,「今回のリクエスト」と「前のリクエスト/レスポンス」とが関連している必要がある やりとりが1回1回は切断されず、連続した状態であることをステートフルと言う. 例)SMTP…クライアントが明示的に切断しない限り、 何度でもリクエスト/レスポンスを繰り返せる。
ステートフルな通信の例: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: 宛先メールアドレス DATA 354 go ahead (本文) . 250 ok 1022650055 qp 17435 QUIT 221 nautilus.crew.sfc.keio.ac.jp Connection closed by foreign host. % 赤文字:自分で入力 黒文字:ホストが出力 普段使うEメール送るためのプロトコルです。 明示的に切断要求
解決編(2) ステートフルにするためにはセッションを管理する必要がある セッションとは,1人の利用者がWebアプリのサービスを利用開始してから終了するまでの一連のやり取り 例)今回はログインしてから投稿や閲覧をしログアウトするまで 一連のやり取り クライアント Webサーバ (ブラウザ)
セッション管理を実現するには? ユーザ(のブラウザ)を識別する ユーザの情報を保管する ユーザ(のブラウザ)とユーザの情報を結びつける 問)どうやって、ユーザ(のブラウザ)を識別するか? 問)どこに、ユーザ情報を保管するか? ブラウザ・サーバ・リクエスト/レスポンス? 問)どうやって、ユーザ(のブラウザ)とユーザ情報を結びつけるか? 識別方法 →保管・結びつけ
セッション管理の実際(1) クライアント サーバ 初回のリクエスト (ブラウザ) 岸君 レスポンス ログインします。 パスワード=CreW パスワードOK! 暗証番号をつくって 岸君の ユーザ情報と 結びつけて保管 して… クライアント (ブラウザ) 初回のリクエスト サーバ ログインします。 パスワード=CreW ログイン名=t00289kk 名前=岸 健司…… 岸君 OK。 次から を 持ってきてね! レスポンス
セッション管理の実際(2) リクエスト サーバ クライアント (ブラウザ) 岸君 レスポンス OK。 投稿します。 です。 タイトル= おや,さっき来たABCさんだ。ユーザ情報を使って投稿 しておこう… リクエスト クライアント (ブラウザ) サーバ 投稿します。 です。 タイトル= “web.xmlの冒頭…” 内容= “気になったので…” 岸君 OK。 レスポンス
セッション管理の実際(3) クライアント 初回のリクエスト サーバ (ブラウザ) 杉浦君 レスポンス ログインします。 パスワードOK! 番号札をつくって 杉浦君の ユーザ情報と 結びつけて… クライアント (ブラウザ) 初回のリクエスト サーバ ログインします。 パスワード=password ログイン名=manabu 名前=杉浦 学…… 杉浦君 OK。 次から を 持ってきてね! レスポンス
セッション管理の利用例 オンラインショッピングのカートシステム 杉浦君が大根をカートに入れると、清算のまでその情報が維持されている。 複数のページにまたがった操作をしても、ちゃんとその間の情報は維持される。 大根を買う杉浦君とにんじんを買う岸君は区別される
サーブレットでセッション管理を実現するには サーブレットではHttpSessionクラスによって,セッション管理を行います HttpSessionがやってくれること セッションID(暗証番号)の発行 セッションIDの受け渡し セッションに結びつけた情報管理 セッションの破棄
セッションの裏方:Cookieって? ブラウザ側にちょっとした情報を維持してもらう仕組み サーバがブラウザに小さなテキスト情報=Cookeiを送る(ユーザ側のHDD等に保存) その後同じサイトを訪れたときに、ブラウザは情報を付加してサーバにリクエストする。 Cookieの例→ HttpSessionが ブラウザに 送ったCookie
HttpSessionの使い方(操作概要) 1.HttpSessionオブジェクトの生成(取得) 2.HttpSessionオブジェクトに情報を結びつける 3.HttpSessionオブジェクトに結びついた情報を取得する 4.HttpSessionオブジェクトを無効にする
セッションオブジェクト生成/取得 「まだセッションオブジェクトがないなら、生成してね」という設定をする. HttpSession session = request.getSession ( true ); 「まだセッションオブジェクトがないなら、生成してね」という設定をする. このユーザのセッション管理が開始してないなら セッション管理を開始するということ.
セッションにユーザ情報を結びつける setAttribute session. (“contributor”, contributor); オブジェクトを保管しなさい session. setAttribute (“contributor”, contributor); キーになるStirng (保管オブジェクトの名札) sessionオブジェクト(岸君用) 岸健司 保管してもらうオブジェクト String contributor=“岸 健司”;
session.setAttribute(“login”,login); セッションには情報を複数結びつけられる session.setAttribute(“login”,login); session.setAttribute(“department”,department); session.setAttribute(“grade”,grade); ※セットできるのはオブジェクト。 自分で作ったものも可能。 intはオブジェクトでないので そのままでは入れられません。
セッション管理中か確認する if(session == null){ 【ログイン中でないときの処理】 } HttpSession session = request.getSession ( false ); まだセッションオブジェクトがないなら、null(空っぽ)を返す if(session == null){ 【ログイン中でないときの処理】 }
セッションから情報を取り出す String contributor = (String)session.getAttribute( "contributor" );
セッションの無効化 強制的に無効化する タイムアウト session.invalidate(); 一定時間以上アクセスのないアイドル状態で無効化する session.setMaxInactiveInterval(秒数); で変更可能。 ※ブラウザを一旦終了すると、以前のセッションが使えなくなります。
セッション無効化の必要性 必要最低限の時間で無効化するべき!! セキュリティ問題 セッションIDは厳重な秘密IDではないので、誰かが入手して悪用するかもしれない。 必要最低限の時間で無効化するべき!! →ログアウトやタイムアウトが必要
HttpSessionの主な使い方まとめ あるユーザに対して、 セッションの生成 HttpSession session=request.getSession(true); セッション( HttpSessionオブジェクト)に情報を結びつける session.setAttribute(キーString,オブジェクト); セッション( HttpSessionオブジェクト)に結びついた情報を取得する HttpSession session=request.getSession(false); session.getAttribute(キーString); セッション( HttpSessionオブジェクト)を無効にする session. invalidate();
では、実習です 題材のプログラムを参考に… セッション管理を利用した機能を自分の掲示板に追加してください。 基本的には、「会員制にしてみる」 どうしても嫌な人は…相談。自分で考えてみる。例えば 本日の投稿回数を投稿を受け付けたときに表示する(Integerクラスの利用…) 2度目以降の投稿で、1度目に入力した名前などの情報が自動的に入力される(toukou.html→ToukouInputServlet.javaに…) など。 メモ
予備 今日は赤字のところだけわかればOK.