使用Facebook(SocialAuth)登录JSF并保持会话活动

使用Facebook(SocialAuth)登录JSF并保持会话活动,facebook,jsf,login,facebook-login,socialauth,Facebook,Jsf,Login,Facebook Login,Socialauth,我已经在这个问题上纠缠了很长一段时间,并且我已经多次提出了我的问题。我将明确说明这一点,提供以下实现: index.xhtml,短版本 ... <f:event listener="#{userBacking.pullUserInfo}" type="preRenderView" /> <h:commandLink action="#{userBacking.login()}" value="Login" rendered="#{!userBacking.isLogge

我已经在这个问题上纠缠了很长一段时间,并且我已经多次提出了我的问题。我将明确说明这一点,提供以下实现:


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
@会议范围
公共类UserBacking实现可序列化
{
//======================2.实例字段============================
私有静态最终长serialVersionUID=-2262690225818595135L;
/**
*目前这是静态的。将来,谷歌(和其他公司)可能会实现。
*/
public static final String SOCIAL_PROVIDER_ID=“facebook”/$NON-NLS-1$
//======================2.实例字段============================
私人社会授权经理社会授权经理;
私有配置文件userProfile;
//============================6.动作方法=============================
public void login()引发异常
{
最终属性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=SocialAuthConfig.getDefault();
配置加载(道具);
socialAuthManager=新的socialAuthManager();
setSocialAuthManager.setSocialAuthConfig(配置);
最终字符串authenticationURL=SocialAuthenticationManager.getAuthenticationUrl(社交提供者ID,successURL());
重定向(authenticationURL);
}
public void logout()引发异常
{
socialAuthManager.disconnectProvider(SOCIAL\u PROVIDER\u ID);
ContextHelper.invalidateSession();
}
/*
*如果Facebook出现重定向,应该填写个人资料。。。。
*/
public void pullUserInfo()引发异常
{
if(userProfile==null&&socialAuthManager!=null)
{
最终HttpServletRequest请求=(HttpServletRequest)ContextHelper.ectx().getRequest();
最终映射reqParam=SocialAuthUtil.getRequestParametersMap(req);
最终AuthProvider AuthProvider=socialAuthManager.connect(reqParam);
userProfile=authProvider.getUserProfile();
重定向(ContextHelper.getContextPath());
}
}
//===========================================================================================================================7.获得者和获得者======================
公共配置文件getUserProfile()
{
返回userProfile;
}
公共布尔值isLoggedIn()
{
返回userProfile!=null;
}
//============================9.方便的方法========================
私有静态字符串successURL()
{
返回iaapplicationConstants.APP_PSEUDO_URL+ContextHelper.getContextPath();
}
}

我的故事

  • 如果浏览器中不存在Facebook会话,则可以正常工作。如果我已经登录,则当请求参数中出现
    code
    时,
    socialAuthManager
    似乎为空

  • 我使用
    index.xhtml
    进行登录和回调

  • f:event
    在每次视图呈现时激发
    pullUserInfo()
    ,希望在方法激发时,请求参数中提供一个
    code
    。我知道这是完全错误的

  • 这可以通过一个过滤器来完成吗(即当Facebook用
    代码回拨时)

  • 我不是最大的JSF专家,所以我可能缺少一些基本知识


参考资料


答案很简单,同时也很愚蠢

我正在从
http://devel-win8:1381/app/login
,但可在
http://dev-machine:1381/app/callback
(这是一个不同的实现,使用servlet,但也可以使用问题中的代码)

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

干杯

/**
 * 
 * @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();
    }

}