我正在使用Spring Social和Thymeleaf从快速入门示例开发,但我意识到它每个控制器只支持一个Facebook对象。这意味着样本无法为多个用户提供支持,我猜测它与变量的@Scope有关。它运行在Spring引导容器中,我想知道如何配置它以便每个会话都有自己的Facebook对象。
答案 0 :(得分:2)
正如您所建议的那样,Facebook对象应该配置请求范围。如果您正在使用配置支持和/或Spring Boot,那么它将是请求范围。因此,即使控制器使用Facebook实例注入一次,该实例实际上也是一个代理,它将委托给在经过身份验证的用户请求时创建的真实FacebookTemplate实例。
我只能假设您在http://spring.io/guides/gs/accessing-facebook/引用了入门指南示例。在这种情况下,它可以使用Spring Social的最简单的Spring Boot自动配置,其中包括UserIdSource的基本(但不是用于生产)实现,它始终返回" anonymous"作为用户ID。因此,在您创建第一个Facebook连接后,第二个浏览器会尝试找到"匿名"的连接,找到它,并为您提供授权的Facebook对象。
这可能看起来很奇怪,但它是一个旨在让你入门的示例应用程序......它就是这样做的。要获得真正的UserIdSource,您需要做的就是将Spring Security添加到项目中。这将告诉Spring Social自动配置配置一个UserIdSource,它从安全上下文中获取当前用户ID。这反映了对Spring Social的更实际的使用,虽然显然更多地涉及并超出了入门指南的范围。
但是你可以在https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase-boot看一下Spring Boot中Spring Social的更完整的例子。
答案 1 :(得分:2)
Spring Boot会在幕后自动配置很多东西。它可以自动配置Facebook,LinkedIn和Twitter属性,并为社交提供商建立连接工厂。
但是,UserIdSource的实现始终返回“anonymous”作为用户ID。建立第一个Facebook连接后,第二个浏览器将尝试找到它找到的“匿名”连接,并为您提供授权的Facebook对象。
@Configuration
@EnableSocial
@ConditionalOnWebApplication
@ConditionalOnMissingClass("org.springframework.security.core.context.SecurityContextHolder")
protected static class AnonymousUserIdSourceConfig extends SocialConfigurerAdapter {
@Override
public UserIdSource getUserIdSource() {
return new UserIdSource() {
@Override
public String getUserId() {
return "anonymous";
}
};
}
}
解决方案
The solution将覆盖“anonymous”作为每个新用户/会话的UserId。因此,对于每个会话,我们可以简单地返回一个SessionID,但是,它可能不够独特,无法识别用户,特别是如果它被缓存或存储在连接数据库中的某个位置。
@Override
public String getUserId() {
RequestAttributes request = RequestContextHolder.currentRequestAttributes();
String uuid = (String) request.getAttribute("_socialUserUUID", RequestAttributes.SCOPE_SESSION);
if (uuid == null) {
uuid = UUID.randomUUID().toString();
request.setAttribute("_socialUserUUID", uuid, RequestAttributes.SCOPE_SESSION);
}
return uuid;
}
The solution for above problem has been talked about in detail over here