Webセッション
4D Webサーバーは、Webセッション を管理するビルトインの機能を提供します。 Webセッションを作成・維持することで、Webアプリケーション上のユーザーエクスペリエンスを管理・向上することができます。 Webセッションが有効かされていると、Webクライアントはリクエスト間で同じコンテキスト (セレクションや変数の値) を再利用できます。
Webセッションでは、以下のことが可能です:
- 同一のWebクライアントからの複数のリクエストを、無制限のプリエンプティブプロセスで同時に処理 (Webセッションは スケーラブルです)。
Session
オブジェクトと Session API を介したセッションの管理。- セッションの .storage を使用して、Webクライアントのプロセス間でデータを保存および共有。
- セッションを実行しているユーザーに権限を関連付ける。
用途
Webセッションは次のものに使用されます:
- HTTPリクエストを送信する Webアプリケーション
- リモートデータストア や Qodlyフォーム が使用する REST 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セッション専用に使用されます。
RESTリクエストのための Webセッションを作成するには、利用可能なライセンスが必要な場合があります。詳細は こちらのページ を参照ください。
カレントセッションの Session
オブジェクトは、あらゆる Webプロセスのコードにおいて Session
コマンドを介してアクセスできます。
Webプロセスは通常終了せず、効率化のためにプールされリサイクルされます。 プロセスがリクエストの実行を終えると、プールに戻され、次のリクエストに対応できるようになります。 Webプロセスはどのセッションでも再利用できるため、実行終了時には (CLEAR VARIABLE
などを使用し) コードによって プロセス変数 をクリアする必要があります 。 このクリア処理は、開かれたファイルへの参照など、プロセスに関連するすべての情報に対して必要です。 これが、セッション関連の情報を保持したい場合には、Session オブジェクトを使用することが 推奨 される理由です。
セッション情報の保存と共有
各 Session
オブジェクトには、共有オブジェクトである .storage
プロパティが用意されています。 このプロパティにより、セッションで処理されるすべてのプロセス間で情報を共有することができます。
セッションの有効期限
スケーラブルWebセッションは、以下の場合に閉じられます:
- Webサーバーが停止したとき。
- セッションcookie がタイムアウトしたとき。
非アクティブな cookie の有効期限は、デフォルトでは 60分です。つまり、Webサーバーは、非アクティブなセッションを 60分後に自動的に閉じます。
このタイムアウトは、Session
オブジェクトの .idleTimeout
プロパティで設定できます (タイムアウトは 60分未満にはできません)。また、Open datastore
コマンドの connectionInfo パラメーターを使っても設定できます。
Webセッションが閉じられた後に Session
コマンドが呼び出されると:
Session
オブジェクトには権限が含まれていません (ゲストセッション)。.storage
プロパティは空です。- 新しいセッションcookie がセッションに関連付けられています。
ログアウト 機能を使用して、Qodly フォームからのセッションを閉じることができます。
権限
Webユーザーセッションには、権限を関連付けることができます。 セッションの権限に応じて、特定のアクセスや機能を Webサーバー上で提供することができます。
権限を割り当てるには、.setPrivileges()
関数を使用します。 コード内では、.hasPrivilege()
関数を使ってセッションの権限をチェックし、アクセスを許可または拒否することができます。 デフォルトでは、新しいセッションは権限を持たず、ゲスト セッションとなります (.isGuest()
関数は true を返します)。
例:
If (Session.hasPrivilege("WebAdmin"))
// アクセス権が付与されているので、何もしません
Else
// 認証ページを表示します
End if
権限は ORDAアーキテクチャーの中心に実装されており、データストアやデータクラス関数へのアクセスを制御するための強力な技術を開発者に提供します。 詳細については、ORDA の章の 権限 を参照ください。
例題
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("パスワードに誤りがあります")
End if
Else
WEB SEND TEXT("この userId は登録されていません")
End if