JSF Войти через Facebook (SocialAuth) и поддерживать сессию в живых
Я застрял в этом вопросе довольно долго, и я переформулировал свой вопрос несколько раз. Я буду в явном виде с этим, предоставляя реализацию ниже:
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 не существует в браузере. Если я уже вошел в систему, кажется, что
socialAuthManager
NULL, когдаcode
в запросе появляется params.я использую
index.xhtml
для входа и обратного вызова.f:event
пожарыpullUserInfo()
каждый раз, когда представление рендерится, надеясь, что при запуске метода,code
в параграфе запроса. Я знаю, что это все неправильно.Это можно сделать с помощью фильтра (например, когда Facebook перезванивает с
code
)?Я не самый большой эксперт по JSF, поэтому я могу упустить некоторые базовые знания.
Рекомендации
1 ответ
Ответ довольно прост и в то же время глуп.
Сеанс теряется и создается как новый в каждом запросе сервлета
Я запускаю логин от http://devel-win8:1381/app/login
, но обратный вызов найден в http://dev-machine:1381/app/callback
(это другая реализация с сервлетами, но она также будет работать с кодом в вопросе).
Браузер создает другой сеанс для "голых" имен хостов.
Приветствия.