我一直在这个问题上停留了很长一段时间,并且我重新提出了几次我的问题。我会明确这一点,提供以下实现: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专家,所以我可能会缺少一些基本知识。
参考