開發基礎:登入輔助
- 詳細內容
- 分類:smartfoxserver
- 發佈:2014-03-02, 週日 23:46
- 點擊數:1577
» 登入輔助元件
幾乎每個應用程式都會需要一個基於密碼的使用者存取,而撰寫程式碼以處理客戶端參數與比對資料庫的檢查是相當繁雜且重複的。
登入輔助元件是個輔助類別,可以輔助開發者建立資料庫驅動的登入系統,而省去了自己撰寫資料庫存取程式碼的麻煩。
簡而言之,它是這樣運作的:
- 在你的資料庫區域中配置DBManager
- 在你的擴展中使用init()來初始化元件
- 配置元件
» 部屬登入輔助元件
假如你使用 SmartFoxServer 2X v2.7.0或是更新的版本,省略這個步驟,因為此元件已經包含在內。
若不是的話,為了要在SmartFoxServer 2X中激活此元件,所有需要做的事情是:
- 在此下載元件(維克:請至官網下載)
- 在你的SFS2X/lib/ 資料夾中解壓縮jar檔
- 重新啟動SmartFoxServer 2X
» 基本的使用Basic usage
在開始之前,先確認在區域配置(Zone configuration)中,設置好資料庫的存取。設置資料庫的方法是,打開SFS2X AdminTool,點選 Zone Configurator模組,並且選擇Database Manager分頁標籤。你會在這篇文章(documentation page)中發現更多的過程的細節。
在這個範例中,我們會使用簡單的user表,其中有下面幾個欄位:
id | name | pword | |
---|---|---|---|
1 | Kermit | thefrog | kermit@muppets.com |
2 | Gonzo | thegreat | gonzo@muppets.com |
3 | Fozzie | thebear | fozzie@muppets.com |
4 | MissPiggy | thepig | piggy@muppets.com |
下一步我們建立新的擴展,並且在init()方法中使用這些程式碼:
public class MuppetsExtension extends SFSExtension { private LoginAssistantComponent lac; @Override public void init() { lac = new LoginAssistantComponent(this); // Configure the component lac.getConfig().loginTable = "muppets"; lac.getConfig().userNameField = "name"; lac.getConfig().passwordField = "pword"; } public void destroy() { lac.destroy(); } }
我們要做的事情僅僅只是指定好所要使用的表格名稱,以及代表使用者名稱與密碼的欄位來配置元件。瞧!元件現在已經配置好了,能夠使用正確的欄位,並且能檢查驗證,發出錯誤,以及淨化使用者資料以避片SQL的注入攻擊。
»一個稍微再進階一點的例子
讓我們假設有一個稍微再複雜一點的場景,使用者將使用email位址登入,而系統中的使用者名稱必須與資料庫中的name欄位相關聯。另外,我們也想要確認使用者名稱的檢查是大小寫區分的。
(維克:從程式碼來看,就是將email當成登入帳號,密碼依然需要。)
事實上,預設情況下大部分的資料庫檢查字串時並不會區分大小寫,除非使用特定的校正方式。登入助手能夠使用DB中指定的欄位來作為登入名稱,讓我們來看看這怎麼做:
@Override public void init() { lac = new LoginAssistantComponent(this); // Configure the component lac.getConfig().loginTable = "muppets"; lac.getConfig().userNameField = "email"; lac.getConfig().passwordField = "pword"; lac.getConfig().nickNameField = "name"; lac.getConfig().useCaseSensitiveNameChecks = true; }
需要的只是多出兩行程式碼,用來指定nick name欄位,並且開啟大小寫檢查。
注意:
假如你有興趣學習更多關於資料庫字串比對與校正,請查看這些額外的資源:
» StackOverflow: SQL Case Sensitive String Compare
» MySQL: Case Sensitivity in String Searches
» 進階功能
讓我們嘗試使事情變得複雜一些。假設我們的數據庫中包含一些額外的欄位:頭像圖像和用來標示用戶是否具有主持人權限的旗標。
id | name | pword | avatar | isMod | |
---|---|---|---|---|---|
1 | Kermit | thefrog | kermit@muppets.com | kermit.jpg | Y |
2 | Gonzo | thegreat | gonzo@muppets.com | gonzo.jpg | N |
3 | Fozzie | thebear | fozzie@muppets.com | fozzie.png | Y |
4 | Miss Piggy | thepig | piggy@muppets.com | piggy.png | N |
我們將影像名稱儲存至客戶端的Session物件中,這樣一來當我們接收USER_JOIN_ZONE事件時就能藉由使用者變數來設定影像(User Variables)。另外,假如資料庫的旗標是設定的話,我們也想要能夠設定客戶端為主持人。
登入助手提供一個簡單的方法,透過preProcessPlugin 與 postProcessPlugin類別在檢查驗證之前與之後加入客製化的邏輯。讓我們來看看這如何運作:
@Override public void init() { lac = new LoginAssistantComponent(this); // Configure the component lac.getConfig().loginTable = "muppets"; lac.getConfig().userNameField = "email"; lac.getConfig().passwordField = "pword"; lac.getConfig().nickNameField = "name"; lac.getConfig().useCaseSensitiveNameChecks = true; lac.getConfig().extraFields = Arrays.asList("avatar", "isMod"); lac.getConfig().postProcessPlugin = new ILoginAssistantPlugin () { public void execute(LoginData loginData) { ISFSObject fields = loginData.extraFields; String avatarPic = fields.getUtfString("avatar"); boolean isMod = fields.getUtfString("isMod").equalsIgnoreCase("Y"); // Store avatar in session object loginData.session.setProperty("avatar", avatarPic) // Set client as Moderator if (isMod) loginData.session.setProperty("$permission", DefaultPermissionProfile.MODERATOR); } }; }
我們已經新增了一個新的配置參數稱之為extraFields, 這個參數包含了我們想在登入時選擇的客製化欄位名稱列表。
在下一行中,我們藉由行內的宣告來傳遞postProcessPlugin類別,為了方便,他是個匿名類別。這類別需要實現 ILoginAssistantPlugin介面,而這介面中宣告了execute()方法。
就像你看到的,在這方法中我們傳遞了所有相關的登入資料,包含了所有從資料庫取出的欄位(以SFSObject來表示)以及客戶端Session物件。這是一個非常簡單的方法來提供額外的邏輯到登入過程中,而不需要撰寫客製化的登入處理器。
藉由參考com.smartfoxserver.v2.components.login套件中的server-side javadoc,你可以找到在這例子中所有提到類別的細節。
» 處理錯誤
關於錯誤驗證,拒絕存取,重複使用者名稱等等的錯誤,都是由登入輔助元件使用標準的 SmartFoxServer 2X規則處理,這意味著所有的錯誤訊息都能夠被在客戶端藉由SFSErrorCodes class客製化。
開發者所負責的唯一地方是在 pre-process 與 post-process 中處理例外。在這些類別中任何的執行期間例外將會上升到SFS2X API執行緒中,並且在這裡被捕捉與紀錄。這也意味著它們將中斷登入流程,因此它是由你來決定哪些例外需要被抓取(為了不中斷登入流程)與哪個可以中斷登入過程。