ユーザーセッション
4D Webサーバーは、ユーザーセッション を管理するビルトインの機能を提供します。 ユーザーセッションを作成・維持することで、Webアプリケーション上のユーザーエクスペリエンスを管理・向上することができます。 ユーザーセッションが有効かされていると、Webクライアントはリクエスト間で同じコンテキスト (セレクションや変数の値) を再利用できます。
Webサーバーのユーザーセッションでは、以下のことが可能です:
- 同一のWebクライアントからの複数のリクエストを、無制限のプリエンプティブプロセスで同時に処理 (Webサーバーセッションは スケーラブルです)。
- Webクライアントのプロセス間でデータを共有。
- ユーザーセッションに権限を関連付ける。
Session
オブジェクトと Session API を介したアクセスの処理。
注: 現在の実装は、Webアプリケーション全体においてセッションを介して階層的なユーザー権限を開発者が管理できるようにする、今後予定されている包括的な機能の最初のステップに過ぎません。
セッションの有効化
セッション管理機能は、4D Webサーバー上で有効または無効にすることができます。 セッション管理を有効化する方法は複数あります:
- ストラクチャー設定の Web / オプション (I) ページの スケーラブルセッション を使用する (永続的な設定):
このオプションは、新規プロジェクトではデフォルトで選択されています。 これは、セッションなし オプションを選択して無効にすることもできます。この場合、Webセッション機能は無効になります (Session
オブジェクトは使用できません)。
- Webサーバーオブジェクトの
.scalableSession
プロパティを使用する (.start()
関数に settings 引数として渡します)。 この場合、ストラクチャー設定ダイアログボックスで定義されたオプションよりも、Webサーバーオブジェクトの設定が優先されます (ディスクには保存されません)。
メインの Webサーバーのセッションモードは、
WEB SET OPTION
コマンドを使って設定することもできます。
いずれの場合も、設定はマシンに対しローカルなものです。つまり、4D Server の Webサーバーと、リモートの 4Dマシンの Webサーバーで異なる設定が可能です。
互換性について: 4D v18 R6 以前の 4Dバージョンで作成されたプロジェクトでは、旧式セッション オプションが使用できます (詳細については、doc.4d.com の Webサイトを参照ください)。
セッションの実装
セッションを有効にする と、4D自身が設定したプライベート cookie ("4DSID_AppName"、AppName はアプリケーションプロジェクトの名称) に基づいて、自動メカニズムが実装されます。 この cookie は、アプリケーションのカレントWebセッションを参照します。
この cookie の名前は、
.sessionCookieName
プロパティを使用して取得できます。
-
Webサーバーは、各Webクライアントリクエストにおいて、プライベートな "4DSID_AppName" cookie の存在と値をチェックします。
-
cookie に値がある場合、4D は既存セッションの中からこのクッキーを作成したセッションを探し、見つかった場合には再利用します。
-
クライアントからのリクエストが、すでに開かれているセッションに対応していない場合:
- プライベートな "4DSID_AppName" cookie を持つ新しいセッションが Webサーバー上に作成されます。
- 新しいゲスト
Session
オブジェクトが作成され、このスケーラブルWebセッション専用に使用されます。
カレントの Session
オブジェクトは、あらゆる Webプロセスのコードにおいて Session
コマンドを介してアクセスできます。
Webプロセスは通常終了せず、効率化のためにプールされリサイクルされます。 プロセスがリクエストの実行を終えると、プールに戻され、次のリクエストに対応できるようになります。 Webプロセスはどのセッションでも再利用できるため、実行終了時には (
CLEAR VARIABLE
などを使用し) コードによって プロセス変数 をクリアする必要があります 。 このクリア処理は、開かれたファイルへの参照など、プロセスに関連するすべての情報に対して必要です。 これが、セッション関連の情報を保持したい場合には、Session オブジェクトを使用することが 推奨 される理由です。
情報の共有
各 Session
オブジェクトには、共有オブジェクトである .storage
プロパティが用意されています。 このプロパティにより、セッションで処理されるすべてのプロセス間で情報を共有することができます。
セッションの有効期限
スケーラブルWebセッションは、以下の場合に閉じられます:
- Webサーバーが停止したとき。
- セッションcookie がタイムアウトしたとき。
非アクティブな cookie の有効期限は、デフォルトでは 60分です。つまり、Webサーバーは、非アクティブなセッションを 60分後に自動的に閉じます。
このタイムアウトは、Session
オブジェクトの .idleTimeout
プロパティで設定できます (タイムアウトは 60分未満にはできません)。
スケーラブルWebセッションが閉じられた後に Session
コマンドが呼び出されると:
Session
オブジェクトには権限が含まれていません (ゲストセッション)。.storage
プロパティは空です。- 新しいセッションcookie がセッションに関連付けられています。
権限
セッションには、権限を関連付けることができます。 セッションの権限に応じて、特定のアクセスや機能を Webサーバー上で提供することができます。
権限を割り当てるには、.setPrivileges()
関数を使用します。 コード内では、.hasPrivilege()
関数を使ってセッションの権限をチェックし、アクセスを許可または拒否することができます。 デフォルトでは、新しいセッションは権限を持たず、ゲスト セッションとなります (.isGuest()
関数は true を返します)。
現在の実装では (v18 R6)、"WebAdmin" アクセス権のみ利用可能です。
例:
If (Session.hasPrivilege("WebAdmin"))
// アクセス権が付与されているので、何もしません
Else
// 認証ページを表示します
End if
例題
CRMアプリケーションを使って、各営業担当者が自分の顧客ポートフォリオを管理します。 データストアには、少なくとも 2つのリンクされたデータクラス Customers と SalesPersons が含まれています (営業担当者は複数の顧客を持ちます)。
営業担当者がログインし、Webサーバー上でセッションを開き、上位3名の顧客をセッションに読み込ませたいとします。
- セッションを開くために以下の URL を実行します:
http://localhost:8044/authenticate.shtml
本番環境では、暗号化されていない情報がネットワーク上を流れるのを防ぐために、HTTPS接続 を使用する必要があります。
authenticate.shtml
ページは、userId と password の入力フィールドを含むフォームで、4DACTION の POSTアクションを送信します:
<!DOCTYPE html>
<html>
<body bgcolor="#ffffff">
<FORM ACTION="/4DACTION/authenticate" METHOD=POST>
UserId: <INPUT TYPE=TEXT NAME=userId VALUE=""><br/>
Password: <INPUT TYPE=TEXT NAME=password VALUE=""><br/>
<INPUT TYPE=SUBMIT NAME=OK VALUE="Log In">
</FORM>
</body>
</html>
- authenticate project メソッドは、userID に合致する担当者を探し、SalesPersons テーブルに保存されているハッシュ値をパスワードと照合します。
var $indexUserId; $indexPassword; $userId : Integer
var $password : Text
var $userTop3; $sales; $info : Object
ARRAY TEXT($anames; 0)
ARRAY TEXT($avalues; 0)
WEB GET VARIABLES($anames; $avalues)
$indexUserId:=Find in array($anames; "userId")
$userId:=Num($avalues{$indexUserId})
$indexPassword:=Find in array($anames; "password")
$password:=$avalues{$indexPassword}
$sales:=ds.SalesPersons.query("userId = :1"; $userId).first()
If ($sales#Null)
If (Verify password hash($password; $sales.password))
$info:=New object()
$info.userName:=$sales.firstname+" "+$sales.lastname
Session.setPrivileges($info)
Use (Session.storage)
If (Session.storage.myTop3=Null)
$userTop3:=$sales.customers.orderBy("totalPurchase desc").slice(0; 3)
Session.storage.myTop3:=$userTop3
End if
End use
WEB SEND HTTP REDIRECT("/authenticationOK.shtml")
Else
WEB SEND TEXT("This password is wrong")
End if
Else
WEB SEND TEXT("This userId is unknown")
End if