如何通过Spring Social Facebook注册新用户? [英] How to sign up new user via Spring Social Facebook?
问题描述
我有一个网站(Angular App),可以在 https://localhost:4200 和一个 https://localhost:8443 上的服务器(纯REST API).
I am having a website (Angular App) which I can reach on https://localhost:4200 and a server (pure REST API) that is on https://localhost:8443.
由于REST端点是安全的,所以用户必须登录我的服务器.显然,我希望用户能够使用Facebook注册并在登录后进一步与我的服务器通信.
Since the REST endpoints are secured, a user must login on my server. Obviously I want users to be able to signup using Facebook and further communicate with my server after login.
根据
这就是为什么有一个按钮可以做到这一点的原因: that is why there is a button that does just this: 从那里开始,一切正常工作了一段时间.用户被重定向到Facebook的授权页面,单击授权按钮.之后,用户将被重定向到 https://localhost:8443/signin/facebook . From there, everything works fine for some time. The user gets redirected to Facebook's authorization page where the authorization button gets clicked. After that the user gets redirected to https://localhost:8443/signin/facebook. 似乎默认情况下,如果用户未知,将存在另一个重定向到 https://localhost :8443/signup ( It seems that per default, in case the user is unknown, there will be a another redirect to https://localhost:8443/signup (see docs) 如果提供商用户ID与多个现有连接匹配,则 If the provider user ID matches more than one existing connection, 在我的服务器上,这看起来像这样(从示例应用程序借来的 ): On my serer this looks like this (borrowed from a sample application): 这是我的问题: 首先,我需要知道我在该端点应该做什么.用户授权了我的应用程序,但是我的服务器尚不知道该用户,所以 First of all I need to know what I am supposed to do at this endpoint. The user authorized my app, but my server does not know the user yet so do I 第二,我不知道应该如何从此处重定向回我的网站,正如所述,该网站位于 https://localhost:4200 .但是,当然,我的服务器不知道这一点. Second, I do not know how I am supposed to redirect back to my website from here which, as explained, lies on https://localhost:4200. But of course, my server does not know that. 有人可以引导我完成这一过程吗? Is there a chance somebody can guide me through this? 这是 与Spring Social相关的Maven依赖项: Maven dependencies related to Spring Social:
这是我的 This is my 指向笔记: 我检索在 I retrieve the connection object set in 这是一个简单的PoC代码,应对其进行修改以符合您的业务逻辑. This is a simple PoC code , it should be modified to conform to your business logic. 也许您可以显示一个表格供用户填写他的昵称或地址或其他内容.这取决于您的业务逻辑. Maybe you can display a form for user to fill-in his nickname or address or something. That's depend on your business logic. 这篇关于如何通过Spring Social Facebook注册新用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!POST /signin/{providerId}
-启动登录流程.
POST /signin/{providerId}
- Initiates the sign in flow. <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>
ProviderSignInController
将重定向到应用程序的登录URL,从而为用户提供通过另一提供商或使用其用户名和密码登录的机会.登录URL的请求会将查询参数"error
"设置为"multiple_users
",以指示问题,以便页面可以将其传达给用户.默认的登录URL是"/signin
"(相对于应用程序根目录),但可以通过设置signInUrl
属性进行自定义.
ProviderSignInController
will redirect to the application’s sign in URL to offer the user a chance to sign in through another provider or with their username and password. The request to the sign in URL will have an "error
" query parameter set to "multiple_users
" to indicate the problem so that the page can communicate it to the user. The default sign in URL is "/signin
" (relative to the application root), but can be customized by setting the signInUrl
property.@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()
并将新用户保存到我的数据库中
connection.fetchUserProfile()
and save the new user to my databaseSocialConfig
@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());
}
}
<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>
推荐答案
signup
PoC代码,仅供参考signup
PoC code , 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链接到本地用户.ProviderSignInController.handleSignIn()
, it contains freshy (not mapped in db) providerId/providerUserId pair.
And I create a new local user , give it random username/password pair , and link the new providerId/providerUserId to the local user.