Web Application 開 發 利 器 - WebSnap! 第 五 章 、 使 用 者 管 理 及 Sessions
在 以 往 的 WebBroker+InternetExpress 架 構 下 , 我 們 處 理 使 用 者 控 制 或 是 Session 管 理 都 很 麻 煩 ,WebSnap 加 強 了 這 部 份 的 能 力 , 利 用 WebSnap 來 處 理 使 用 者 或 是 Session 是 一 件 非 常 簡 單 的 事 情 , 接 下 來 我 們 就 為 我 們 的 程 式 加 上 這 些 功 能 。
5-1 使 用 者 管 理 及 Sessions 實 作
要 在 WebSnap 程 式 中 使 用 Session 及 使 用 者 控 制 功 能 的 話 , 你 必 需 在 Application Module 中 加 入 三 個 元 件 :TEndUserSessionAdapter 、 TWebUserList 、 TSessionServices 。 TEndUserSessionAdapter 繼 承 至 TEndUserAdapter 並 加 入 了 Session 的 處 理 , 簡 單 的 說 她 只 是 把 使 用 者 的 資 料 存 入 Session 中 而 已 。 TWebUserList 則 負 責 儲 存 使 用 者 資 料 及 驗 證 的 工 作 , TSessionServices 是 整 個 WebSnap Application Session 控 管 的 核 心 元 件 , 當 網 頁 被 啟 動 時 TWebAppComponents 會 呼 叫 TSessionServices 來 產 生 一 個 Session 給 來 訪 者 , 接 著 再 將 這 個 Session 傳 給 WebContext 保 存 。 當 送 出 Response 時 將 SessionID 封 裝 成 Cookie 一 併 送 給 使 用 者 , 接 下 來 的 Request 就 會 以 Cookie 將 這 個 SessionID 送 回 給 我 們 的 程 式 。 有 了 這 個 SessionID 我 們 就 可 以 取 得 上 次 Session 中 的 資 料 了 , 這 些 動 作 會 受 到 Cookie 的 保 存 時 限 與 Session 的 保 存 時 限 所 影 響 , 當 Cookie 過 期 或 是 Session 的 時 限 到 期 亦 或 者 是 你 重 新 啟 動 了 程 式 後 Session 就 視 同 消 失 了 , 以 下 是 WebSnap 處 理 Session 的 流 程 :
( 圖 :6)
當 你 放 好 這 些 元 件 後 , 你 還 要 設 定 TWebUserList 中 的 使 用 者 資 料 , 請 雙 按 她 的 UserItems 特 性 值 來 加 入 使 用 者 資 料 , 並 設 定 其 ID 與 密 碼 資 料 :
這 個 範 例 中 除 了 TEndUserSessionAdapter 會 將 使 用 者 資 料 存 放 在 Session 之 外 , 我 們 也 搭 個 便 車 使 用 一 下 Session 物 件 。 請 你 在 TEndUserSessionAdapter 中 加 入 一 個 AdapterField 名 稱 是 AdaptAge:
接 著 撰 寫 她 的 OnGetValue 事 件 , 加 入 以 下 的 程 式 碼 :
if not VarIsEmpty(Session.Values[''''Age'''']) then
Value:=Session.Values[''''Age'''']
else Value:='''''''';
上 面 這 一 段 程 式 碼 是 用 來 確 定 Session 中 是 否 有 一 個 Age 的 值 , 有 的 話 就 存 入 Value 變 數 中 。 這 樣 我 們 就 可 以 在 Home Module 的 Script 中 加 入 以 下 的 程 式 來 顯 示 這 個 值 :
<h1> 歡 迎 <%=EndUser.DisplayName %> 你 今 年 是 <%=EndUser.AdaptAge.Value%> 歲 </h1>
定 義 語 系 ( 以 免 被 當 成 其 它 語 系 網 頁 )
<meta http-equiv="Content-Type" content="text/html; charset=big5">
然 後 我 們 要 新 增 一 個 Page Module 來 讓 使 用 者 登 入 系 統 , 請 選 擇 AdapterPageProducer 並 將 PageName 設 為 Login , 接 著 在 裡 面 放 入 一 個 TLoginFormAdapter 元 件 。 由 於 我 們 希 望 搭 Login 的 便 車 讓 使 用 者 填 入 額 外 的 資 料 , 因 此 除 了 TLoginFormAdapter 預 設 的 三 個 AdapterField 元 件 之 外 , 我 們 還 要 額 外 加 入 一 個 AdapterField 元 件 :
完 成 後 我 們 還 得 撰 寫 AdaptAge 的 OnUpdateValue 事 件 , 將 輸 入 的 值 存 入 Session 中 :
procedure TLogin.AdaptAgeUpdateValue(Sender: TObject; Value: Variant);
begin
Session.Values[''''Age'''']:=AdaptAge.ActionValue.Values[0];
end;
然 後 我 們 就 可 以 開 啟 Visual Page Designer 來 設 計 我 們 的 登 入 網 頁 了 , 整 個 畫 面 如 下 :
最 後 回 到 Application Module 將 TEndUserSessionAdapter 的 LoginPage 特 性 值 設 為 Login( 登 入 網 頁 的 PageName) 就 完 成 了 。
那 我 們 要 如 何 將 一 個 網 頁 設 定 為 使 用 者 必 須 預 先 登 入 才 能 進 入 的 呢 ? 你 有 兩 種 選 擇 , 一 是 在 建 立 Page Module 時 將 Login Required 選 項 打 勾 , 另 一 個 是 手 動 去 改 變 Page Module 的 特 性 值 , 這 個 範 例 中 我 要 將 Edit 這 個 網 頁 設 定 成 需 要 先 登 入 才 能 訪 問 的 網 頁 , 因 此 我 將 Edit 內 的 程 式 碼 做 下 列 的 修 改 :
WebRequestHandler.AddWebModuleFactory(TWebPageModuleFactory.Create(TEdit, TWebPageInfo.Create(
[wpPublished , wpLoginRequired],''''.html''''),crOnDemand, caCache));
完 成 後 就 可 以 執 行 程 式 來 看 看 成 果 了 , 正 常 的 話 使 用 者 必 須 要 Login 之 後 才 能 訪 問 Edit 網 頁 , 這 點 倒 是 很 正 常 , 但 你 有 沒 有 發 現 到 一 個 問 題 :
上 圖 中 我 們 看 到 了 使 用 者 可 以 改 變 NextPage 來 選 擇 Login 後 導 向 的 網 頁 , 這 在 很 多 情 況 下 不 適 用 , 因 為 我 們 可 能 不 想 讓 使 用 者 改 變 這 個 設 定 , 我 們 可 能 想 要 在 程 式 中 判 斷 或 是 將 這 個 值 設 死 。 以 目 前 的 TLoginFormAdapter 來 看 , 這 個 NextPage 屬 性 是 保 護 層 級 的 , 那 也 代 表 著 我 們 無 法 改 變 她 , 據 DELPHI R&D 的 說 法 是 Patch 後 就 會 公 開 這 個 屬 性 了 , 目 前 我 們 可 以 使 用 以 下 的 技 巧 來 完 成 這 個 動 作 :
TProtectedLoginFormAdapter=class(TLoginFormAdapter);
… … … … … .
TProtectedLoginFormAdapter(LoginFormAdapter1).NextPage:=''''Home'''';
如 果 你 看 過 我 的 另 一 篇 文 章 的 話 , 那 這 個 技 巧 對 你 來 說 應 該 是 蠻 熟 悉 的 。 你 可 以 將 這 段 程 式 碼 放 至 在 Module 的 Activate 事 件 中 , 當 你 成 功 登 入 系 統 並 選 擇 Next Page 為 Code6421 的 首 頁 後 , 你 應 該 會 看 到 這 樣 的 畫 面 :
這 樣 你 應 該 清 楚 了 Session 的 運 用 了 吧 , 那 我 們 可 以 在 Session 中 存 入 那 些 型 態 的 資 料 呢 ? 理 論 上 只 要 是 Variant 所 支 援 的 型 態 就 可 以 存 入 Session 中 。
5-2 保 存 期 限 的 控 制
這 個 範 例 大 概 可 以 滿 足 大 部 份 的 需 求 , 但 你 看 到 以 下 的 畫 面 後 可 能 就 不 太 認 同 了 :
上 圖 中 我 開 啟 了 一 個 網 頁 登 入 後 又 另 外 再 開 啟 另 一 個 IE 網 頁 , 結 果 你 可 以 發 現 到 你 必 須 在 第 二 個 網 頁 中 再 登 入 一 次 , 這 在 許 多 情 況 下 是 不 適 用 的 。 這 是 因 為 Cookie 的 保 存 期 限 設 定 所 造 成 的 後 果 , 我 們 可 以 藉 由 設 定 Cookie 的 保 存 期 限 來 解 決 這 個 問 題 :
uses DateUtils;
… ..
procedure THome.WebAppComponentsBeforeDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
I:Integer;
begin
for I:=0 to WebContext.Response.Cookies.Count-1 do
begin
if SameText(WebContext.Response.Cookies.Items[I].Name,''''WebBrokerSessionID'''') then
begin
if WebContext.Response.Cookies.Items[I].Expires = -1 then
WebContext.Response.Cookies.Items[I].Expires:=IncDay(Date);
end;
end;
end;
在 上 面 的 程 式 我 們 將 Cookie 的 保 存 期 限 設 為 一 天 , 然 後 你 再 啟 動 程 式 後 就 正 常 了 :
除 了 多 個 IE 視 窗 的 問 題 外 , 如 果 我 們 的 使 用 者 資 料 是 存 放 在 資 料 庫 中 時 要 如 何 做 呢 ? 看 以 下 的 片 段 程 式 你 就 清 楚 了 :
procedure THome.WebUserListBeforeValidateUser(Strings: TStrings;
var UserID: Variant; var Handled: Boolean);
begin
if Strings.Count > 0 then
UserID:=Strings.Values[''''UserName''''];
Handled:=True;
end;
上 圖 中 我 只 是 單 純 的 記 錄 使 用 者 所 輸 入 的 資 料 , 也 就 是 說 不 管 他 是 誰 都 可 以 通 過 驗 證 。 你 可 以 在 這 裡 面 加 入 由 資 料 庫 中 取 得 資 料 並 與 使 用 者 輸 入 的 資 料 作 比 對 的 程 式 碼 , 成 功 的 話 才 把 使 用 者 名 稱 設 給 UserID 。 當 你 將 名 稱 設 給 UserID 後 , 就 代 表 著 該 使 用 者 已 通 過 驗 證 , 在 傳 入 的 Strings 參 數 中 有 兩 個 值 , 一 個 是 UserName , 另 一 個 就 是 Password 了 。
5-3 權 限 的 控 管
除 了 基 本 的 使 用 者 控 制 外 , WebSnap 也 提 供 了 權 限 的 控 管 , 範 圍 由 Page 到 Action 都 有 , 你 可 以 試 著 設 定 某 個 Page 的 xxxxAccess 特 性 值 來 處 理 權 限 的 控 制 。
WebRequestHandler.AddWebModuleFactory(TWebPageModuleFactory.Create(TMasterDetailEdit,
TWebPageInfo.Create([wpPublished {, wpLoginRequired}], ''''.html''''), crOnDemand, caCache));
[1] [2] [3] 下一页 [聊天工具]Gmail推出新功能:Web Clip__天极Yesky [聊天工具]Web MSN你玩了吗__天极Yesky [系统软件]Web Browser Express 概述 [系统软件]对Internet Explorer Web 控件做一点修改 [常用软件]小技巧:三步实现Web迅雷录制PPLive节目 [常用软件]天网防火墙:打开WEB和FTP服务 [VB.NET程序]使用VB.Net做一个配置web.config功能的WinForm(原… [VB.NET程序]vb.net控件、web service简述 [VB.NET程序]使用vbscript脚本调用web服务 [VB.NET程序]*** Web 存储系统窗体:窗体注册表 (new)***
|