【问题标题】:Spring Social Facebook春季社交脸书
【发布时间】:2015-01-07 21:18:03
【问题描述】:

我正在从快速入门示例中使用 Spring Social 和 Thymeleaf 进行开发,但我意识到它仅支持每个控制器一个 Facebook 对象。这意味着该示例无法为多个用户提供支持,我猜它与变量的 @Scope 有关。它在 Spring 引导容器中运行,我想知道如何配置它,以便每个会话都有自己的 Facebook 对象。

【问题讨论】:

  • 我认为您会在默认自动配置的情况下为每个请求获得一个 Facebook(只需将其注入您的控制器,它就已经是一个请求范围的代理)。是什么让您认为它不起作用?
  • 因为当我用另一个浏览器查看时,它假定我是同一个用户。
  • 定义另一个浏览器?使用 CTRL+N 打开的新选项卡或浏览器窗口不是新浏览器。启动多个 Chrome 或 Firefox 实例也会导致会话附件。
  • 这是在应用程序级别,这意味着我尝试了一个完全不同的浏览器,并且我确认通过打印会话 ID 创建了一个新会话。但 Facebook 对象在会话中保持授权
  • 您是否使用了 Spring Social Facebook 的自动配置支持?还是你自己配置的?

标签: spring-mvc spring-boot thymeleaf spring-social spring-social-facebook


【解决方案1】:

正如您所建议的,Facebook 对象应该配置有请求范围。如果您正在使用配置支持和/或 Spring Boot,那么它将是请求范围的。因此,即使控制器被注入一次 Facebook 实例,该实例实际上是一个代理,它将委托给一个真实的 FacebookTemplate 实例,该实例是在请求时为经过身份验证的用户创建的。

我只能假设您指的是http://spring.io/guides/gs/accessing-facebook/ 上的入门指南示例。在这种情况下,它为 Spring Social 使用最简单的 Spring Boot 自动配置,其中包括 UserIdSource 的基本(但不用于生产)实现,它始终返回“匿名”作为用户 ID。因此,在您创建第一个 Facebook 连接后,第二个浏览器会尝试为“匿名”找到一个连接,找到它,并为您提供一个授权的 Facebook 对象。

这可能看起来很奇怪,但它一个旨在让您入门的示例应用程序......它确实做到了。要获得真正的 UserIdSource,您需要做的就是将 Spring Security 添加到项目中。这将告诉 Spring Social 自动配置配置一个从安全上下文中获取当前用户 ID 的 UserIdSource。这反映了对 Spring Social 的更真实的使用,尽管显然涉及更多并且超出了入门指南的范围。

但您可以查看https://github.com/spring-projects/spring-social-samples/tree/master/spring-social-showcase-boot 以获得更完整的 Spring Boot 中的 Spring Social 示例。

【讨论】:

【解决方案2】:

Spring Boot 在幕后自动配置了很多东西。它会自动配置 Facebook、LinkedIn 和 Twitter 属性,并为社交提供者设置连接工厂。

但是,UserIdSource 的实现总是返回“匿名”作为用户 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 将覆盖“匿名”作为每个新用户/会话的 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 2014-09-21
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    相关资源
    最近更新 更多