Как зарегистрировать нового пользователя через Spring Social Facebook? - PullRequest
0 голосов
/ 08 мая 2018

У меня есть веб-сайт (приложение Angular), к которому я могу подключиться на https://localhost:4200, и сервер (чистый REST API), который находится на https://localhost:8443.

С конечных точек RESTзащищены, пользователь должен войти в систему на моем сервере.Очевидно, что я хочу, чтобы пользователи могли зарегистрироваться через Facebook и далее общаться с моим сервером после входа в систему.


Согласно документам

POST /signin/{providerId} - инициирует вход в поток.

, поэтому есть кнопка, которая делает именно это:

<form ngNoForm name="fb_signin" id="fb_signin" action="https://localhost:8443/signin/facebook" method="POST">
  <input type="hidden" name="scope" value="email">
  <button type="submit">SIGNING</button>
</form>

Оттуда все работает хорошо в течение некоторого времени.Пользователь перенаправляется на страницу авторизации Facebook, где нажимается кнопка авторизации.После этого пользователь перенаправляется на https://localhost:8443/signin/facebook.


Похоже, что по умолчанию, если пользователь неизвестен, будет еще одно перенаправление на https://localhost:8443/signup ( см.docs )

Если идентификатор пользователя провайдера соответствует более чем одному существующему соединению, ProviderSignInController перенаправит на URL-адрес приложения для входа, чтобы предоставить пользователю возможность войти через другого провайдера илис их именем пользователя и паролем.Запрос на URL входа будет иметь параметр запроса «error», установленный на «multiple_users», чтобы указать проблему, чтобы страница могла сообщить ее пользователю.URL для входа по умолчанию - «/signin» (относительно корня приложения), но его можно настроить, установив свойство signInUrl.

На моем сервере это выглядит так (* 1041)* заимствовано из примера приложения ):

@RequestMapping(value = "/signup", method = RequestMethod.GET)
public SignUpForm signupForm(WebRequest request) {
    Connection<?> connection = providerSignInUtils.getConnectionFromSession(request);
    if (connection != null) {
        request.setAttribute("message", new Message(MessageType.INFO, "Your " + StringUtils.capitalize(connection.getKey().getProviderId()) + " account is not associated with a Spring Social Showcase account. If you're new, please sign up."), WebRequest.SCOPE_REQUEST);
        return SignUpForm.fromProviderUser(connection.fetchUserProfile());
    } else {
        return new SignUpForm();
    }
}

И вот мои проблемы:

Прежде всего мне нужно знать, что я должен делать на этой конечной точке.Пользователь авторизовал мое приложение, но мой сервер еще не знает пользователя, поэтому я могу

  • connection.fetchUserProfile() и сохранить нового пользователя в моей базе данных
  • что-то еще?

Во-вторых, я не знаю, как я должен перенаправить обратно на мой сайт отсюда, который, как объяснено, лежит на https://localhost:4200. Но, конечно, мой сервер не знает этого.

Есть ли шанс, что кто-нибудь может мне помочь в этом?


Это SocialConfig

@Configuration
@EnableSocial
public class SocialConfig implements SocialConfigurer {

    private final static Logger LOGGER = LogManager.getLogger(SocialConfig.class);

    @Value("${spring.social.facebook.appId}")
    String facebookAppId;

    @Value("${spring.social.facebook.appSecret}")
    String facebookSecret;

    @Autowired
    private DataSource dataSource;

    @Bean
    @Scope(value="singleton", proxyMode = ScopedProxyMode.INTERFACES)
    public ConnectionFactoryLocator connectionFactoryLocator() {
        ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();

        registry.addConnectionFactory(new FacebookConnectionFactory(
                facebookAppId,
                facebookSecret
        ));

        return registry;
    }

    @Bean
    @Scope(value="singleton", proxyMode=ScopedProxyMode.INTERFACES)
    public UsersConnectionRepository usersConnectionRepository() {
        return new JdbcUsersConnectionRepository(dataSource, connectionFactoryLocator(), Encryptors.noOpText());
    }

    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
        LOGGER.debug("Adding connection factories");
        cfConfig.addConnectionFactory(new FacebookConnectionFactory(
                env.getProperty("facebook.clientId"),
                env.getProperty("facebook.clientSecret")));

    }

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

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

    @Bean
    public ProviderSignInController providerSignInController(
            ConnectionFactoryLocator connectionFactoryLocator,
            UsersConnectionRepository usersConnectionRepository) {
        ProviderSignInController controller = new ProviderSignInController(
                connectionFactoryLocator,
                usersConnectionRepository,
                new SimpleSignInAdapter(new HttpSessionRequestCache()));

        return controller;
    }

    @Bean
    public RequestCache requestCache() {
        return new HttpSessionRequestCache();
    }

    @Bean
    public SignInAdapter signInAdapter() {
        return new SimpleSignInAdapter(new HttpSessionRequestCache());
    }

}

Maven-зависимостей, связанных с Spring Social:

<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-facebook</artifactId>
    <version>3.0.0.M1</version>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-security</artifactId>
    <version>2.0.0.M4</version>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-core</artifactId>
    <version>2.0.0.M2</version>
</dependency>
<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-config</artifactId>
    <version>2.0.0.M2</version>
</dependency>

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Это мой signup код PoC, FYI

@Controller
class HomeController : AbstractController() {

  private var sessionStrategy: SessionStrategy = HttpSessionSessionStrategy()

  @Inject
  private lateinit var connectionFactoryLocator: ConnectionFactoryLocator

  @Inject
  private lateinit var usersConnectionRepository: FoodUsersConnectionRepository

  @RequestMapping("/")
  fun index(): String {
    logger.info("index")
    return "index"
  }

  @RequestMapping("/signup")
  fun signup(nativeWebRequest: NativeWebRequest) : String {
    sessionStrategy.getAttribute(nativeWebRequest , ProviderSignInAttempt.SESSION_ATTRIBUTE)
      .takeIf { it != null }
      .also { it ->
        val attempt = it as ProviderSignInAttempt
        val connection = attempt.getConnection(connectionFactoryLocator)
        logger.info("conn.key = {}" , connection.key)
        val user = userDao.save(User(RandomStringUtils.randomAlphanumeric(8) , RandomStringUtils.randomAlphanumeric(8)))
        val connRepo: ConnectionRepository = usersConnectionRepository.createConnectionRepository(user.id.toString())
        connRepo.addConnection(connection)
      }
    return "signup"
  }

}

Очки к заметкам:

Я получаю объект соединения, установленный в ProviderSignInController.handleSignIn(), он содержит свежую (не сопоставленную в db) пару providerId / providerUserId. И я создаю нового локального пользователя, назначаю ему случайную пару имя пользователя / пароль и связываю новый providerId / providerUserId с локальным пользователем.

Это простой код PoC, его следует изменить, чтобы он соответствовал вашей бизнес-логике.

Может быть, вы можете отобразить форму для пользователя, чтобы ввести свой псевдоним или адрес или что-то еще. Это зависит от вашей бизнес-логики.

0 голосов
/ 16 мая 2018

После этого пользователь перенаправляется на https://localhost:8443/signin/facebook.

Я думаю, что есть еще один лучший способ сделать это. Как ваше угловое веб-приложение (https://localhost:4200) состоит из веб-слоя, поэтому прямое перенаправление через действие формы не является лучшим способом. Вы можете использовать Маршрутизация прокси нажмите здесь

Теперь, если вы используете, вы используете прокси-маршрутизацию, вам нужно настроить прокси-порт (8443) с помощью команды.

ng serve –proxy-config proxy.conf.json
где proxy.conf.json содержит вашу конфигурацию https://localhost:8443/

Затем вам необходимо сначала аутентифицировать каждого пользователя / нового пользователя на вашем сервере (уровень обслуживания), а затем передавать каждый запрос через контроллер уровня обслуживания пользователя. Это приведет к тому, что каждый запрос будет проходить через ваш сервер, и это решит вашу проблему.

Пользователь авторизовал мое приложение, но мой сервер еще не знает пользователя, поэтому я

...