2014-05-19 52 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,但它会在该问题的代码以及工作)。

浏览器为“裸”主机名创建不同的会话。

干杯。