社交化 Spring 应用程序

工程 | Craig Walls | 2010年11月03日 | ...

如今,网民越来越多地使用互联网通过社交网站与朋友、家人和同事建立联系。曾经通过电子邮件进行的对话现在发生在 Facebook 墙上的短消息或 Twitter 上的简短推文中。曾经通过握手建立的联系现在通过 LinkedIn 建立。当希望面对面会面时,可以使用 TripIt 共享旅行详情。

正如人们使用这些社交网站相互交流一样,企业也在寻找方法将自己注入社交图谱,以便以更个人的方式与客户建立联系,并使他们的网站成为客户社交体验的延伸。

本周,我们很高兴发布了 Spring Social 的第一个里程碑版本,这是一个 Spring 的新扩展,旨在提供一个平台,用于构建具有社交功能的 Spring 应用程序。我想借此机会向您介绍 Spring Social,并让您初步了解它提供的功能。

安全共享社交数据

表面上看,开发与各种社交网络交互的应用程序似乎很简单。由于大多数社交网络都提供 REST API,Spring 的 RestTemplate 似乎就是您所需要的。但您很快会发现,这些社交 REST API 受 OAuth 保护,并且使用 OAuth 凭据签署通过 RestTemplate 发送的请求是一项非琐碎的任务。

OAuth 是一种开放协议,它允许用户与其在一个或多个服务提供商上托管的数据共享给另一个应用程序。通过访问这些数据,应用程序可以聚合、呈现和处理信息,从而提供超出服务提供商本身预期或设想的附加价值。

几乎所有主要的提供商都支持 OAuth,包括 Twitter、Facebook、LinkedIn、TripIt 和 Foursquare,以及 Google 和 Yahoo API。因此,OAuth 对于开发具有社交功能的应用程序至关重要。

在 OAuth 安全交互的开始阶段,有一个来回的对话,通常称为“OAuth 舞步”。在典型的 OAuth 舞步中,涉及三方:

  • 服务提供商(例如 Twitter 或 LinkedIn)
  • 希望访问或更新该服务提供商托管数据的用户。
  • 用户希望与之共享数据的消费者应用程序。

此舞步的关键步骤如下:

  1. 消费者应用程序将用户重定向到服务提供商的站点进行登录并授权消费者。
  2. 假设用户同意授予消费者访问其数据的权限,则流程将返回到消费者应用程序。
  3. 消费者应用程序从服务提供商处收到访问令牌。

步骤 3 中收到的访问令牌是任何请求服务提供商 REST API 都必须附带的“代客钥匙”。在 OAuth 1 中,这意味着访问令牌、请求 URL、参数以及其他一些信息被收集到一个基本字符串中,进行加密,然后作为 Authorization 标头发送到请求中。构造此标头并将其附加到请求是一项复杂的任务。这就是为什么使用 RestTemplate 访问 OAuth 安全资源很困难的原因。如果操作错误,服务提供商将对您尝试访问的任何资源响应 HTTP 401,并且对加密的 Authorization 标头进行调试很棘手。

使用社交模板

Spring Social 的一个关键组件是其社交模板集合。这些模板(在底层利用 RestTemplate)暴露了它们所模拟的服务提供商的操作,并处理了添加 OAuth Authorization 标头的复杂性。

Spring Social 1.0.0.M1 包含 4 个社交模板供您选择:

  • TwitterTemplate
  • FacebookTemplate
  • LinkedInTemplate
  • TripItTemplate

要使用这些模板中的任何一个,只需创建一个实例,通过构造函数参数提供 OAuth 连接详细信息。例如,创建 TwitterTemplate 的实例:

TwitterTemplate twitter = new TwitterTemplate(apiKey, apiSecret, accessToken, accessTokenSecret);

TwitterTemplate 构造函数中的四个参数都是 String 类型。API 密钥和 API 密钥在您向 Twitter 注册应用程序时获得(请参阅 http://dev.twitter.com/apps/new)。访问令牌和访问令牌密钥是在 OAuth 舞步与 Twitter 结束时按用户授予您的应用程序的。此时,我将假设您已经获得了这四个值;我们稍后会回到如何管理 API 密钥和令牌。

创建其他社交模板的实例并没有太大区别。LinkedInTemplateTripItTemplate 各自具有与上面显示的 TwitterTemplate 构造函数相同的参数列表的构造函数。由于 Facebook 的 API 安全性基于 OAuth 2,FacebookTemplate 的构造函数更简单,只需要访问令牌的值。

FacebookTemplate facebook = new FacebookTemplate(accessToken);

一旦您拥有了其中一个社交模板的实例,您可以用它做什么?如果您使用的是 TwitterTemplate,也许您想知道已认证用户的 Twitter 屏幕名称?

String screenName = twitter.getProfileId();

或者,如果您想做一些更复杂的事情,也许您可以代表用户发送一条推文?

twitter.updateStatus("Hey, I'm tweeting with #Spring Social!");

同样,有了 FacebookTemplate,您可以发布到用户的墙上。

facebook.updateStatus("Spring Social can also post to Facebook!");

如果您想查看用户的即将到来的旅行行程,TripItTemplategetTrips() 可以满足您的需求。

List trips = tripIt.getTrips();
for(Trip trip : trips) {
    System.out.println("I'm traveling to " + trip.getPrimaryLocation() +
                                 " on " + trip.getStartDate());
}

这只是 Spring Social 模板可以做的一些事情的示例。请查看 API 文档以了解可用的其他操作。

管理 OAuth 连接

当我上面创建 TwitterTemplate 实例时,我省略了 API 密钥/密钥和访问令牌的来源。起初,访问令牌将在用户授权应用程序访问其在服务提供商处托管的数据后获得。但您可能不希望每次用户使用您的应用程序时都强制他们进行授权,因此您需要一种方法来长期存储访问令牌,以便在将来的会话中重复使用。

在其第一个里程碑版本中,Spring Social 没有提供 OAuth 令牌管理策略,而是让应用程序自行获取和管理 OAuth 详细信息。这是我们计划在 1.0 Milestone 2 中解决的问题。但在此之前,我们可以参考 Greenhouse 来了解这可能如何成形。

在 Greenhouse 中,有关服务提供商的所有信息都存储在关系数据库的 ServiceProvider 表中,其架构如下:

如您所见,ServiceProvider 表包含提供商的 API 密钥和密钥等信息。为了访问单个服务提供商记录,Greenhouse 使用 JdbcServiceProviderFactory,它是 ServiceProvider 接口的实现。

package com.springsource.greenhouse.connect;

public interface ServiceProviderFactory {

    ServiceProvider getServiceProvider(String name);

    <S> ServiceProvider<S> getServiceProvider(String name, Class<S> serviceType);

}

要从数据库中检索 Twitter 服务提供商,Greenhouse 只需调用 getServiceProvider() 方法,并将“twitter”(服务提供商的名称)作为参数传入。在 Twitter 的情况下,这最终会返回 TwitterServiceProvider 的一个实例,它是 ServiceProvider 接口的一个实现。

ServiceProvider 有几个方法,但有两个方法在令牌管理方面很有意思。第一个是 connect(),Greenhouse 使用它来在其用户与其在服务提供商上的社交身份之间建立连接。

void connect(Long accountId, AuthorizedRequestToken requestToken);

在调用 connect() 方法时,Greenhouse 已经完成了足够的 OAuth 流程,手中持有一个授权的请求令牌。将这些令牌与用户的帐户 ID 一起传递,将在 AccountConnection表中创建一个连接。AccountConnection表具有以下架构。

在建立连接后,您可以使用 ServiceProvidergetServiceOperations() 方法来获取 TwitterOperations 的一个实例(TwitterTemplate 基于该接口)。

TwitterOperations twitter = twitterProvider.getServiceOperations(accountId);

getServiceOperations() 的内部,ServiceProvider 实现会检索访问令牌,并将其与自己的 API 密钥和密钥一起用于构建 TwitterTemplate,从而使应用程序不必直接处理访问令牌。

在 Greenhouse 中,TwitterOperations 实例是一个请求范围的 bean,通过 ServiceProvidersApiConfiguration 中的一个工厂方法创建,使用 Spring JavaConfig 如下:

@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public TwitterOperations twitter(ServiceProvider<TwitterOperations> twitterProvider, @Value("#{request.getAttribute('account')}") Account account) {

    return twitterProvider.getServiceOperations(accountId(account));

}

作为 Spring bean,TwitterOperations 可以注入到任何需要与 Twitter 交换数据的其他 Spring bean 中。例如,在 Greenhouse 中,EventsController 是处理所有事件导向请求的 Web 交互的 Spring MVC 控制器。它使用 TwitterOperations 代表用户发布关于事件的推文。它通过其构造函数注入了 TwitterOperations bean。


@Inject
public EventsController(EventRepository eventRepository, TwitterOperations twitterApi) {
    this.eventRepository = eventRepository;
    this.twitterApi = twitterApi;
}

正如我所提到的,我们打算在第二个里程碑中将 ServiceProvider 功能从 Greenhouse 迁移到 Spring Social。显然,当前的实现支持 OAuth 详细信息的 relacion 存储,但我们渴望听到您关于在其他类型的存储中维护 OAuth 信息的其他实现的建议。

运行 Greenhouse

虽然您可以在 http://greenhouse.springsource.org 处查看正在运行的 Greenhouse 应用程序,但您可能希望检出 Greenhouse 源代码并亲自尝试,以便在探索 Spring Social 的同时进行。为此,请按照以下步骤操作:

  1. 检出 Greenhouse 源代码
    git clone git://git.springsource.org/greenhouse/greenhouse.git
  2. 将 Greenhouse 项目导入 SpringSource Tool Suite
  3. 将 Greenhouse 项目拖到 SpringSource tcServer(在 Servers 选项卡下)以部署应用程序。
  4. 编辑 tcServer 的运行配置,在 VM 参数列表的末尾添加“-DspringProfiles=embedded”。
  5. 启动服务器,并在浏览器中访问 https://:8080/greenhouse。

第 4 步是必需的,因为 Greenhouse 使用了 Spring 3.1 的新环境 bean 功能,该功能可以识别仅为特定配置文件创建的 bean。设置此属性表明应用程序应在“embedded”配置文件下运行。

结论

Spring Social 1.0 M1 是将社交网络功能引入 Spring 的激动人心的征程的第一步。我鼓励您 下载 Spring Social检出代码,并通过 问题跟踪Spring Social 论坛Greenhouse 邮件列表 提供反馈。

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有