2014-05-19 85 views
0

我一直在這個問題上停留了很長一段時間,並且我重新提出了幾次我的問題。我會明確這一點,提供以下實現:JSF使用Facebook(SocialAuth)登錄並保持Session的活躍狀態


index.xhtml,簡短版本。

... 
<f:event listener="#{userBacking.pullUserInfo}" type="preRenderView" /> 

<h:commandLink action="#{userBacking.login()}" value="Login" rendered="#{!userBacking.isLoggedIn()}"/> 
<h:commandLink action="#{userBacking.logout()}" value="Logout" rendered="#{userBacking.isLoggedIn()}" /> 

<h:outputText rendered="#{userBacking.isLoggedIn()}" value="#{userBacking.userProfile.fullName}" /> 
... 


UserBacking.java

/** 
* 
* @author ggrec 
* 
*/ 
@ManagedBean 
@SessionScoped 
public class UserBacking implements Serializable 
{ 

    // ==================== 2. Instance Fields ============================ 

    private static final long serialVersionUID = -2262690225818595135L; 

    /** 
    * This is static for now. In the future, Google (and others) may be implemented. 
    */ 
    public static final String SOCIAL_PROVIDER_ID = "facebook"; //$NON-NLS-1$ 


    // ==================== 2. Instance Fields ============================ 

    private SocialAuthManager socialAuthManager; 

    private Profile userProfile; 


    // ==================== 6. Action Methods ============================= 

    public void login() throws Exception 
    { 
     final Properties props = System.getProperties(); 
     props.put("graph.facebook.com.consumer_key", FACEBOOK_APP_ID); //$NON-NLS-1$ 
     props.put("graph.facebook.com.consumer_secret", FACEBOOK_APP_SECRET); //$NON-NLS-1$ 
     props.put("graph.facebook.com.custom_permissions", "email"); //$NON-NLS-1$ //$NON-NLS-2$ 
     final SocialAuthConfig config = SocialAuthConfig.getDefault(); 
     config.load(props); 

     socialAuthManager = new SocialAuthManager(); 
     socialAuthManager.setSocialAuthConfig(config); 

     final String authenticationURL = socialAuthManager.getAuthenticationUrl(SOCIAL_PROVIDER_ID, successURL()); 

     ContextHelper.redirect(authenticationURL); 
    } 


    public void logout() throws Exception 
    { 
     socialAuthManager.disconnectProvider(SOCIAL_PROVIDER_ID); 

     ContextHelper.invalidateSession(); 
    } 

    /* 
    * Should fill up the profile, if a redirect from Facebook appers. Uhhh.... 
    */ 
    public void pullUserInfo() throws Exception 
    { 
     if (userProfile == null && socialAuthManager != null) 
     { 
      final HttpServletRequest req = (HttpServletRequest) ContextHelper.ectx().getRequest(); 
      final Map<String, String> reqParam = SocialAuthUtil.getRequestParametersMap(req); 

      final AuthProvider authProvider = socialAuthManager.connect(reqParam); 

      userProfile = authProvider.getUserProfile(); 

      ContextHelper.redirect(ContextHelper.getContextPath()); 
     } 
    } 


    // ==================== 7. Getters & Setters ====================== 

    public Profile getUserProfile() 
    { 
     return userProfile; 
    } 


    public boolean isLoggedIn() 
    { 
     return userProfile != null; 
    } 


    // ==================== 9. Convenience Methods ======================== 

    private static String successURL() 
    { 
     return IApplicationConstants.APP_PSEUDO_URL + ContextHelper.getContextPath(); 
    } 

} 


我的故事

  • 工作正常,如果一個Facebook會話不會在瀏覽器中存在。如果我已經登錄,當請求參數中的code出現時,似乎socialAuthManager爲NULL。

  • 我使用index.xhtml進行登錄和回調。

  • f:event每次視圖呈現時都會觸發pullUserInfo(),希望在該方法觸發時,請求參數中會提供code。我知道這是完全錯誤的。

  • 這可以通過一個過濾器來完成(即當Facebook回撥code)?

  • 我不是最大的JSF專家,所以我可能會缺少一些基本知識。


參考

回答

1

答案很簡單,同時也很愚蠢。

Session is lost and created as new in every servlet request

我從http://devel-win8:1381/app/login射擊登錄,但回調在http://dev-machine:1381/app/callback發現(這是一個不同的實現,使用servlet,但它會在該問題的代碼以及工作)。

瀏覽器爲「裸」主機名創建不同的會話。

乾杯。