Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook Login with Spring Social using Existing User Access Token

Here's what I currently have:

  • Spring REST service where many of the APIs require the user to be authenticated
  • A 'registration' API (/api/v1/register)
  • A 'login' API that takes username/password (/api/v1/login)
  • 'Facebook Login' API that relies on Spring Social and Spring Security to create a User Connection and log my user in (/auth/facebook)

My problem is that I want these APIs to be used by multiple clients, but the way Facebook Login is right now, it doesn't work well on mobile (works great on a website).

Here's the mobile scenario:

  • I use Facebook's iOS SDK to request permission from the user
  • Facebook returns a user access token
  • I want to send my backend service this token and have Spring Social accept it, create the User Connection, etc.

Can this be done? Or am I going to have to write my own API to persist the User Connection?

Appreciate any help!

like image 422
AlexG Avatar asked Apr 18 '15 02:04

AlexG


People also ask

How do I add OAuth to Facebook?

Click on Settings in the sidebar under Facebook Login. Turn on Client OAuth Login. Turn on Web OAuth Login. Put the valid redirect URL on "Valid OAuth redirect URIs".

Does Facebook Log in use OAuth?

Web OAuth Login settings enables any OAuth client token flows that use the Facebook web login dialog to return tokens to your own website.


1 Answers

I had the exact same issue and here's how I made it work. You probably have a SocialConfigurer somewhere with the following:

@Configuration
@EnableSocial
public class SocialConfig implements SocialConfigurer {

    @Autowired
    private DataSource dataSource;

    @Bean
    public FacebookConnectionFactory facebookConnectionFactory() {
        FacebookConnectionFactory facebookConnectionFactory = new FacebookConnectionFactory("AppID", "AppSecret");
        facebookConnectionFactory.setScope("email");
        return facebookConnectionFactory;
    }

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        cfConfig.addConnectionFactory(facebookConnectionFactory());
    }

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

    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator, Encryptors.noOpText());
    }

    // Other @Bean maybe ...
}

From here, what you can do is, in a Controller/RestController, add a mapping with a RequestParam for your token that you will send to your server:

@Autowired
private FacebookConnectionFactory facebookConnectionFactory;

@Autowired
private UsersConnectionRepository usersConnectionRepository;

@RequestMapping(value = "/my-facebook-url", method = RequestMethod.POST)
public String fb(@RequestParam String token) {
    AccessGrant accessGrant = new AccessGrant(token);
    Connection<Facebook> connection = facebookConnectionFactory.createConnection(accessGrant);

    UserProfile userProfile = connection.fetchUserProfile();
    usersConnectionRepository.createConnectionRepository(userProfile.getEmail()).addConnection(connection);

    // ...

    return "Done";
}

Useful references

  • UsersConnectionRepository
  • ConnectionRepository
like image 190
Philippe Avatar answered Sep 20 '22 16:09

Philippe