建立基於擴展的客製化登入

» 如何建立基於擴展的客製化登入

在伺服端時間一個客製化的登入是很簡單的一個過程。SFS2X會發出下面兩個登入事件:

  • USER_LOGIN(使用者登入): 當客戶端請求加入一個區域時會發出這個事件。你可以在這裡驗證使用者憑證與決定使用者是否能繼續進行登入動作。在這個階段客戶端是以一個Session物件作為代表,還不是一個真正的使用者。
  • USER_JOIN_ZONE(使用者家入區域):當使用者成功加入一個區域(並且轉換成為SFS使用者(SFSUser)) 時會發出此事件。

1) 配置區域

在 AdminTool中打開區域配置模組(Zone Configurator module)並且開啟區域中的"使用客製化登入(Use custom Login)" ,然後重新開啟SFS2X 。

2)伺服器程式

建立一個新的伺服器擴展,並且繼承SFSExtension類別。你的init()方法看起來應該要像這樣:

@Override
public void init() 
{ 
   trace("My CustomLogin extension starts!"); 
     
   // Register for login event 
   addEventHandler(SFSEventType.USER_LOGIN, LoginEventHandler.class); 
}    

現在建立LoginEventHandler 類別用來處理使用者名稱/密碼的檢查。下面範例示範如何拒絕兩個特定名稱使用者的登入。

public class LoginEventHandler extends BaseServerEventHandler 
{ 
   @Override
   public void handleServerEvent(ISFSEvent event) throws SFSException 
   { 
      String name = (String) event.getParameter(SFSEventParam.LOGIN_NAME); 
        
      if (name.equals("Gonzo") || name.equals("Kermit")) 
      {
         
        // Create the error code to send to the client  
        SFSErrorData errData = new SFSErrorData(SFSErrorCode.LOGIN_BAD_USERNAME);
        errData.addParameter(name);
         
        // Fire a Login exception
        throw new SFSLoginException("Gonzo and Kermit are not allowed in this Zone!", errData); 
      }
   } 

兩個拒絕名單中只要有一個被偵測到,SFSException 就會被發出。這樣做可以提供我們訊息,以便記錄在伺服端以及包含錯誤碼與被拒絕的使用者名稱的SFSErrorData中。

這部分常見的錯誤碼是SFSErrorCode.LOGIN_BAD_USERNAME 與SFSErrorCode.LOGIN_BAD_PASSWORD,兩個都帶有一個額外的參數代表錯誤的名稱與密碼。

這是一個非常簡單的例子,只是用來顯示如何拒絕使用者名稱為Kermit 與Gonzo的存取。當然你的邏輯可能需要更為複雜點,但是你應該要了解一個觀念。當你需要停止登入過程時,你只需要丟出一個SFSLoginException例外就可以了。

假如沒有例外被丟出,系統就會接受使用者並且繼續登入的動作。 
在這階段中還有其他事情也可能會出錯,例如::

  • 區域已滿,無法再登入。
  • 其他有相同名稱的使用者已經登入
  • 使用者目前在拒絕列表中。
  • 使用者名稱可能包含不好的字眼而不被接受(取決於custom configuration)
  • 等等…

當所有檢查都通過了,使用者最後會登入到區域中。在這時候伺服端程式碼會接收到一個USER_JOIN_ZONE事件,假如你有訂閱他的話。

這個步驟是選擇性的,而且在大部分的例子中都不需要。

通常當你需要在使用者登入系統後完成特定的動作(像是設定使用者變數,自動加入房間等等)時才會使用。

小貼士:

當與非同步事件,像是 USER_LOGIN and USER_JOIN_ZONE 配合時,要維護目前的交易/操作是有點難度的。
一個維護狀態的方便做法是使用使用者Session 物件。尤其是Session 物件允許儲存客製化參數像是鍵/值對一樣(參考JavaDoc , 方法getProperty/setProperty  等等)。(維克:使用Session 物件來分辨使用者。)

3) 密碼安全

基於安全的理由,使用者密碼絕對不會直接從客戶端傳送到伺服器中。為了要能夠與資料庫中的加密密碼做比較,我們在API中提供一個方便的方法。

getApi().checkSecurePassword(session, clearPass, encryptedPass);

當密碼符合時該方法會傳回true,不相符則傳回false。

在客戶端中,與”標準登入”與”客製化登入”並無不同。需要做的事情就是新增一個監聽器以監聽SFSEvent.LOGIN 事件來接收伺服端的回應。然後送出一個LoginRequest 以登入區域中。(維克:監聽器的設置要早於發出LoginRequest 。以免伺服器回覆時,監聽器根本還沒建立起來。)

你可以看看AS3 documentation與範例 以了解該如何完成這些動作的細節。對於其他語言而言,整個過程都是相同的。關於這個主題的其他有趣的文件請參考: User Permissions.

4) 在登入時間改變使用者名稱

在許多例子中,你會需要將在登入階段中由使用提供的使用者名稱改為由資料庫提取出來的名稱。一個例子就是,使用者使用email作為使用者名稱來登入,但是在資料庫中,你儲存了他的暱稱。而應該使用這個暱稱來代替email。

我們已經建立了一個簡單慣例可以允許你在登入階段中提供一個二選一的名稱。在USER_LOGIN 事件中會傳遞一個空的SFSObject ,可以用來傳回客製化的資料到客戶端中。在一個非常特定(與保留的)主要名稱下,只需要在物件中提供名稱。請看下面的程式碼:

publicclassLoginEventHandler extendsBaseServerEventHandler
{
   @Override
   publicvoidhandleServerEvent(ISFSEvent event) throwsSFSException
   {
      String name = (String) event.getParameter(SFSEventParam.LOGIN_NAME);
      ISFSObject outData = (ISFSObject) event.getParameter(SFSEventParam.LOGIN_OUT_DATA);
        
      // ...
      // your login logic goes here
      // ...
       
      // Provide a new name for the user:
      String newName = "User-"+ name;
      outData.putUtfString(SFSConstants.NEW_LOGIN_NAME, newName);
   }
}
 
 

  按個讚!~支持本站!~

FB推薦載入中