Search code examples
javaspringspring-mvcspring-socialspring-social-facebook

How can I log in with more than one Facebook account?


I am currently trying to get familiar with Spring Social framework. Unfortunately it looks like the code from the tutorial I am following allows only one global login (from the web application point of views).

For example I am connection to Facebook on the laptop I am working on but after opening the app in another browser I am still seeing the details of the user I used in the first place.

Is there a good tutorial which shows how one can authenticate with more than one user at a time?

The "problem" seems to be in the HelloController. Once the user is authorized it is authorized globally for the whole application. How can I change it so it works for multiple logins?

package hello;

import javax.inject.Inject;

import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.api.PagedList;
import org.springframework.social.facebook.api.Post;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/")
public class HelloController {

    private Facebook facebook;

    @Inject
    public HelloController(Facebook facebook) {
        this.facebook = facebook;
    }

    @RequestMapping(method=RequestMethod.GET)
    public String helloFacebook(Model model) {
        if (!facebook.isAuthorized()) {
            return "redirect:/connect/facebook";
        }

        model.addAttribute(facebook.userOperations().getUserProfile());
        PagedList<Post> homeFeed = facebook.feedOperations().getHomeFeed();
        model.addAttribute("feed", homeFeed);

        return "hello";
    }

}

EDIT

Making the Facebook instance as request scoped bean does not bring any change. Here is my code.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.core.env.Environment;
import org.springframework.social.UserIdSource;
import org.springframework.social.config.annotation.ConnectionFactoryConfigurer;
import org.springframework.social.config.annotation.EnableSocial;
import org.springframework.social.config.annotation.SocialConfigurerAdapter;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionFactoryLocator;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.connect.web.ConnectController;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.social.facebook.connect.FacebookConnectionFactory;

import my.social.StaticUserIdSource;

@Configuration
@EnableSocial
@PropertySource("classpath:application.properties")
public class SocialConfig extends SocialConfigurerAdapter {

    @Configuration
    public static class FacebookConfiguration extends SocialConfigurerAdapter {

        @Override
        public void addConnectionFactories(
                ConnectionFactoryConfigurer connectionFactoryConfigurer,
                Environment environment) {
            connectionFactoryConfigurer
                    .addConnectionFactory(new FacebookConnectionFactory(
                            environment.getRequiredProperty("facebook.appId"),
                            environment
                                    .getRequiredProperty("facebook.appSecret")));
        }

        @Bean
        public ConnectController connectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
            ConnectController connectController = new ConnectController(connectionFactoryLocator, connectionRepository);
            return connectController;
        }

        @Bean
        @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
        public Facebook facebookTemplate(ConnectionRepository connectionRepository) {
            Connection<Facebook> connection = connectionRepository.findPrimaryConnection(Facebook.class);
            return connection != null ? connection.getApi() : null;
        }
    }

    @Override
    public UserIdSource getUserIdSource() {
        return new StaticUserIdSource();
    }
}

Solution

  • In your configuration you are using a StaticUserIdSource judging from the name it uses a predefined user-id. As soon as you have registered a user with the given id (after the first authentication with Facebook that is) that will be used for all other users.