Как проверить токен авторизации facebook и зарегистрировать пользователя с помощью Spring (Java) - PullRequest
0 голосов
/ 20 декабря 2018

Я занимаюсь разработкой приложения, внешний интерфейс которого написан с использованием React.js, а внутренний REST API написан с использованием среды Spring.Я хотел добавить социальные логины на свой сайт, поэтому после нескольких дней поисков и поисков я понял, что OAuth2 - это решение.Я узнал, что внешний интерфейс должен обрабатывать получение токена авторизации с сервера ресурсов (здесь Facebook), а мой бэкэнд (java) должен проверять этот токен и соединяться с Facebook, чтобы получить токен доступа.Затем этот токен доступа должен быть сохранен в моей базе данных вместе с данными пользователя (например, электронной почтой).

Вот мое требование, когда пользователь нажимает кнопку «Продолжить с Facebook» , мое приложение должно создать там учетную запись в моей собственной базе данных, используя данные - адрес электронной почты и имя (функция регистрации)).И позже, когда они снова нажмут на эту кнопку, они войдут в систему, а не зарегистрируются.То, как это делают другие веб-сайты.

На данный момент у меня в приложении работает кнопка, которая приносит мне токен авторизации от Facebook.

Может кто-нибудь подсказать мне путь, по которому я долженследуйте здесь.

Кроме того, следует уделить особое внимание некоторой обработке ошибок.

1 Ответ

0 голосов
/ 13 мая 2019

Вот общий подход с использованием Spring Boot в качестве REST API, поддерживаемого Spring Data JPA и Spring Security, которые работают для iOS и ember.js вместе.Вероятно, есть библиотеки и что-то, что вы не можете использовать, но я просто собираюсь обрисовать фундаментальный поток.

  1. Вашему пользовательскому объекту требуется однозначное сопоставление с учетной записью facebook.Передовой опыт включает шифрование authToken перед сохранением в БД
@Entity
class FacebookAccount {

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    Long id

    String facebookUserId
    String authToken

    @OneToOne
    @JoinColumn(name="user_id")
    User user
}
@Entity
class User{

...
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    FacebookAccount facebookAccount
}
Используйте facebook Javascript SDK для получения токена доступа пользователя и идентификатора пользователя Facebook пользователя.Вы получите ответ от Facebook в своем приложении реакции, которое в успешном случае выглядит следующим образом:
{
    status: 'connected',
    authResponse: {
        accessToken: '...',
        expiresIn:'...',
        reauthorize_required_in:'...'
        signedRequest:'...',
        userID:'...'
    }
}

Нажмите на конечную точку входа в систему с информацией, полученной на шаге 2, например /login/facebook.Я не могу предсказать, как ваше приложение структурировано.В моем приложении этот код обрабатывается моим фильтром аутентификации, который реализует GenericFilterBean.Я передаю заголовок X-Auth-Facebook с токеном.

Проверьте токен.Я делаю это в классе, который реализует AuthenticationProvider в методе Authentication authenticate(Authentication authentication) throws AuthenticationException.Для этого класса понадобится токен доступа вашего приложения accessToken и токен пользователя userAccessToken:

URIBuilder builder = URIBuilder.fromUri(String.format("%s/debug_token", "https://graph.facebook.com"))
builder.queryParam("access_token", accessToken)
builder.queryParam("input_token", userAccessToken)
URI uri = builder.build()
RestTemplate restTemplate = new RestTemplate()

JsonNode resp = null
try {
    resp = restTemplate.getForObject(uri, JsonNode.class)
} catch (HttpClientErrorException e) {
    throw new AuthenticationServiceException("Error requesting facebook debug_token", e)
}

Boolean isValid = resp.path("data").findValue("is_valid").asBoolean()
if (!isValid)
    throw new BadCredentialsException("Token not valid")

String fbookUserId = resp.path("data").findValue("user_id").textValue()
if (!fbookUserId)
    throw new AuthenticationServiceException("Unable to read user_id from facebook debug_token response")

// spring data repository that finds the FacebookAccount by facebook user id
FacebookAccount fbookAcct = facebookAccountRepository.findByFacebookUserId(fbookUserId)
if(!fbookAcct){
    // create your user here
    // save the facebook account as well
} else{
  // update the existing users token
  fbookAcct.authToken = userAccessToken
  facebookAccountRepository.save(fbookAcct)
}
// finish the necessary steps in creating a valid Authentication

Лично я создаю токен, который использует мой клиент при доступе к моему API(вместо того, чтобы они продолжали передавать токен Facebook со всеми запросами).

Мне также нужно больше информации, предоставленной пользователем, чтобы создать пользователя (выбранное имя пользователя, согласие с условиями и т. Д.).Таким образом, моя фактическая реализация выдает EntityNotFoundException вместо создания пользователя, который мои клиенты затем используют, чтобы открыть форму регистрации, которая предоставляет только поля, которые я не могу получить из Facebook.Получив это от клиента, я нажал на конечную точку /signup/facebook с помощью токена Facebook и того, что нужно для создания моего пользователя.Я получаю профиль из Facebook и создаю пользователя (автоматически регистрируя их в процессе).

Редактировать: Если вы хотите использовать Spring 0Auth, вы можете воспользоваться примером для создания шаблона отдыха Oauth Spring 2

@Bean
public OAuth2ProtectedResourceDetails facebook() {
    AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
    details.setId("facebook");
    details.setClientId("233668646673605");
    details.setClientSecret("33b17e044ee6a4fa383f46ec6e28ea1d");
    details.setAccessTokenUri("https://graph.facebook.com/oauth/access_token");
    details.setUserAuthorizationUri("https://www.facebook.com/dialog/oauth");
    details.setTokenName("oauth_token");
    details.setAuthenticationScheme(AuthenticationScheme.query);
    details.setClientAuthenticationScheme(AuthenticationScheme.form);
    return details;
}

@Bean
public OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext clientContext) {
    OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), clientContext);
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,
            MediaType.valueOf("text/javascript")));
    template.setMessageConverters(Arrays.<HttpMessageConverter<?>> asList(converter));
    return template;
}

и затем использовать:

public String photos(Model model) throws Exception {
        ObjectNode result = facebookRestTemplate
                .getForObject("https://graph.facebook.com/me/friends", ObjectNode.class);
        ArrayNode data = (ArrayNode) result.get("data");
        ArrayList<String> friends = new ArrayList<String>();
        for (JsonNode dataNode : data) {
            friends.add(dataNode.get("name").asText());
        }
        model.addAttribute("friends", friends);
        return "facebook";
    }

Я принял вышеуказанный запрос для друзей из проекта.не должно быть сложно адаптировать приведенный выше код, который я показал с debug_token, для использования шаблона отдыха Spring OAuth.Надеюсь, это поможет:)

...