2

I need to develop some backend application using spring boot (the best will be 2.0 but 1.5 is ok too) which will allow oauth login with facebook and google. I have following requirements:

  • backend will enable login with google or facebook (and on first login backend have to remember user in DB),
  • backend will publish ONLY rest endpoints,
  • frontend will login into facebook or google and then it will send token to backend, backend will validate token in facebook or google (obviously it depends on token provider) and return some json data.

How can i achieve that? I have seen many tutorials but all of them assume that backend and frontend are connected into one application. For some reasons I really don't want that solution: this backend will propably publish data for few applications. Can you please help me with that? I mean some tutorials, code repo etc...

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
regenti88
  • 63
  • 1
  • 10

1 Answers1

8

Google and Facebook have provided step by step details to integrate with their login and validate the token with backed. You can follow the below steps for details.

Google : https://developers.google.com/identity/sign-in/web/sign-in https://developers.google.com/identity/sign-in/web/backend-auth

Make a rest call https://www.googleapis.com/oauth2/v3/tokeninfo?id_token= to integrate and validate the token with backed, pass the accessToken which recived on successfully logged in with frontend google web plugin and store the info or validate with your DB.

public String getGoogleTokenInfo(String accessToken) throws BadRequestException {
        log.debug("Calling Google API to get token info");
        RestTemplate restTemplate = new RestTemplate();
        String googleResponse = null;
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("https://www.googleapis.com/oauth2/v3/tokeninfo").queryParam("id_token", accessToken);
            log.debug("google login uri {}", uriBuilder.toUriString());
            googleResponse = restTemplate.getForObject(uriBuilder.toUriString(), String.class);
            log.info("Gmail user authenticated successfully, details [{}]", googleResponse.toString());

        } catch (HttpClientErrorException e) {
            log.error("Not able to authenticate from Google");
            try {
                JsonNode error = new ObjectMapper().readValue(e.getResponseBodyAsString(), JsonNode.class);
                log.error(error.toString());
                throw new BadRequestException("Invalid access token");
            } catch (IOException mappingExp) {
                throw new BadRequestException("Invalid user");
            }
        } catch (Exception exp) {
            log.error("User is not authorized to login into system", exp);
            throw new BadRequestException("Invalid user");
        }
        return googleResponse;
    }

Facebook: https://developers.facebook.com/docs/facebook-login/web#example

Make a rest call https://graph.facebook.com/me?access_token= from backed by passing the accessToken which recived on successfully logged in with facebook frontend web plugin to validate the token and get profile info and store the info to your DB.

public String getFacebookProfileInfo(final String accessToken) throws BadRequestException {
        log.debug("Calling Facebook API to validate and get profile info");
        RestTemplate restTemplate = new RestTemplate();
        String facebook = null;
        // field names which will be retrieved from facebook
        final String fields = "id,email,first_name,last_name";
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

            UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("https://graph.facebook.com/me")
                    .queryParam("access_token", accessToken).queryParam("fields", fields);

            log.debug("Facebook profile uri {}", uriBuilder.toUriString());
            facebook = restTemplate.getForObject(uriBuilder.toUriString(), String.class);

            log.info("Facebook user authenticated and profile fetched successfully, details [{}]", facebook.toString());
        } catch (HttpClientErrorException e) {
            log.error("Not able to authenticate from Facebook");
            throw new BadRequestException("Invalid access token");
        } catch (Exception exp) {
            log.error("User is not authorized to login into system", exp);
            throw new BadRequestException("Invalid user";
        }
        return facebook;
    }
Nawal Sah
  • 126
  • 6
  • Thank you. Now i understand that i should validate token manually like You showed me and manually check this in all endpoints that my backend will have, But... what if i want to also add registration form and serve own oauth tokens also? Do you have some simple working code examples? I propably searched through all internet and i didn't find anything :( – regenti88 Nov 24 '18 at 14:30
  • Yes, you can develop your own registration form and use your own token management mechanism, basic JWT auth sample code can be found at git repo https://github.com/nssaga/ums – Nawal Sah Nov 24 '18 at 14:45
  • But then... How should i check token validation? I mean that frontend Will send token and i Will dont know if it is from Google auth server or Facebook or my own. – regenti88 Nov 24 '18 at 17:27
  • You have to use a query parameter or field in request as loginType in your login API and based on that check the token with google or facebook – Nawal Sah Nov 24 '18 at 18:01
  • Ok... I started to develop something: https://github.com/regentidev88/spring-social-example The idea was to add some authentication providers by adding filters and check in all filters if token is good one. At first i started with facebook login. At now it doesnt work: the authentication provider is not even being called :./ Could You please tell me why it doesnt work and... if that part of code is going to the right direction or maybe i am doing it totally wrong? – regenti88 Nov 24 '18 at 21:14
  • EDIT: my code is based on this idea: https://stackoverflow.com/questions/25794680/multiple-authentication-mechanisms-in-a-single-app-using-java-config – regenti88 Nov 24 '18 at 21:36