繁体   English   中英

如何通过Spring Social Facebook注册新用户?

[英]How to sign up new user via Spring Social Facebook?

我有一个网站(Angular App),我可以通过https:// localhost:4200https:// localhost:8443上的服务器(纯REST API)访问。

由于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

如果提供者用户ID与多个现有连接匹配,则ProviderSignInController将重定向到应用程序的登录URL,以便为用户提供通过其他提供者或其用户名和密码登录的机会。 对登录URL的请求将“ error ”查询参数设置为“ multiple_users ”以指示问题,以便页面可以将其传达给用户。 默认登录URL为“ /signin ”(相对于应用程序根目录),但可以通过设置signInUrl属性进行自定义。

在我的服务器上,这看起来像这样( 从示例应用程序中借用 ):

@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());
    }

}

与Spring Social相关的Maven依赖项:

<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>

之后,用户被重定向到https:// localhost:8443 / signin / facebook

我认为还有另一种最好的方法。由于你的angular webapp( https:// localhost:4200 )包含webLayer所以直接通过表单动作重定向不是更好的方法。你可以使用代理路由 点击这里

现在,如果您正在使用代理路由,则需要按命令配置代理端口(8443)。

ng serve -proxy-config proxy.conf.json
其中proxy.conf.json包含您的配置https:// localhost:8443 /

然后,您需要首先向服务器(服务层)验证您的每个用户/新用户,然后通过用户服务层控制器传递每个请求。这将导致通过您的服务器传递每个请求,它将解决您的问题。

用户授权我的应用程序,但我的服务器不知道用户,所以我也是

这是我的signup PoC代码,仅供参考

@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()设置的连接对象,它包含freshy(未在db中映射)providerId / providerUserId对。 我创建一个新的本地用户,给它随机的用户名/密码对,并将新的providerId / providerUserId链接到本地​​用户。

这是一个简单的PoC代码,应该修改它以符合您的业务逻辑。

也许你可以显示一个表格供用户填写他的昵称或地址或其他东西。 这取决于您的业务逻辑。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM