介紹 Spring Social 的服務提供商框架

工程 | Craig Walls | 2011 年 3 月 2 日 | ...

在我之前的帖子中,我向您介紹了 Spring Social 到流行的軟體即服務 (SaaS) API(如 Twitter、Facebook、LinkedIn 和 TripIt)的 Java 繫結。除了提供常見 API 操作的簡單、強型別的 Java 方法外,這些繫結還可以確保每個 HTTP 請求都包含必要的憑據,以便授權您的應用程式代表使用者呼叫 API。

我的第一個帖子沒有解決的問題是:我們如何管理代表使用者呼叫服務 API 所需的憑據? 我很高興地告訴大家,我們現在有了這些問題的答案。

本週早些時候,我們宣佈了 Spring Social 專案第二個里程碑版本的釋出。Spring Social 1.0.0.M2 中最重要的新功能是引入了服務提供商“連線”框架。今天,我想向您介紹這個框架,並向您展示如何使用它來管理與 SaaS 提供商的“連線”。

本文中的示例來自 Spring Social Showcase。要進行跟隨,請克隆儲存庫並按照 README 構建和部署示例應用程式。

獲取 Spring Social

隨著 M2 版本的釋出,Spring Social 已被拆分為多個模組

  • spring-social-core - 服務提供商框架、OAuth 支援和核心類。
  • spring-social-web - 連線控制器和支援型別。
  • spring-social-facebook - 用於連線 Facebook 和支援透過 Facebook 登入應用程式的服務提供商實現。
  • spring-social-twitter - 用於連線 Twitter 和支援透過 Twitter 登入應用程式的服務提供商實現。
  • spring-social-linkedin - 用於連線 LinkedIn 的服務提供商實現。
  • spring-social-tripit - 用於連線 TripIt 的服務提供商實現。
  • spring-social-github - 用於連線 GitHub 的服務提供商實現。
  • spring-social-gowalla - 用於連線 Gowalla 的服務提供商實現。
  • spring-social-test - 支援測試服務提供商實現和 API 繫結。

根據您的需求,您不一定需要所有這些模組。最少,您需要核心模組。您可以將其新增到 Maven 構建的專案中,如下所示:


<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-core</artifactId>
    <version>1.0.0.M2</version>
</dependency>

在您可能在 Web 應用程式中使用 Spring Social 的情況下,您還需要 Web 模組


<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-web</artifactId>
    <version>1.0.0.M2</version>
</dependency>

然後,您需要新增一個或多個提供商模組。在我們的示例中,我們將討論將 Twitter 連線新增到應用程式,因此我們需要 twitter 模組


<dependency>
    <groupId>org.springframework.social</groupId>
    <artifactId>spring-social-twitter</artifactId>
    <version>1.0.0.M2</version>
</dependency>

由於我們正在基於 Spring Social 的預覽版本進行開發,因此我們需要將 Spring 的預覽儲存庫新增到 pom.xml 檔案中


<repository>
	<id>org.springframework.maven.milestone</id>
	<name>Spring Maven Milestone Repository</name>
	<url>http://maven.springframework.org/milestone</url>
	<snapshots><enabled>false</enabled></snapshots>
</repository>

請注意,雖然 Spring Social 1.0.0.M2 對 Spring Framework 3.1 有編譯時依賴,但 Spring Social 與 Spring Framework 3.0.x 配合使用效果也很好。

解決了構建中的依賴關係後,我們就可以為應用程式新增 Twitter 連線功能了。

連線 Twitter

為了幫助理解 Spring Social 的服務提供商“連線”框架能帶來什麼,讓我們快速瀏覽一下示例應用程式。

登入示例應用程式後,您首先會看到一個列表,其中列出了示例應用程式支援連線的服務提供商:Twitter、Facebook 和 TripIt。它們應該都顯示您的賬戶尚未與其中任何一個連線。

如果您點選 Twitter 連結,您將被重定向到一個連線狀態頁面,並有機會“連線到 Twitter”。您還會看到一個複選框,如果勾選,將在連線到 Twitter 後釋出一條關於 Spring Social Showcase 的推文。

點選“連線到 Twitter”按鈕後(是否勾選“釋出推文…”複選框由您決定),您將被重定向到 Twitter 的授權頁面,該頁面應該看起來像這樣:

如果您已登入 Twitter,則不會顯示使用者名稱和密碼欄位。但無論哪種情況,您都有機會拒絕或允許示例應用程式訪問和更新您在 Twitter 上的資料。當您點選“允許”按鈕授予許可權時,Twitter 將重定向回示例應用程式,並在示例賬戶和您的 Twitter 個人資料之間建立一個連線。您將看到一個連線狀態頁面,這次會表明存在一個連線。

此時,您可以選擇與 Twitter 斷開連線(如果您願意)。但目前,請返回主頁,您會看到您已連線到 Twitter。

如果您點選“Twitter”連結,並且存在一個可用連線,您將被帶到 Twitter Showcase 頁面,該頁面顯示了您的個人資料圖片、Twitter 顯示名稱和 Twitter 螢幕名稱等內容。您還可以選擇從這裡連線另一個 Twitter 賬戶(您可以將多個提供商賬戶連線到一個應用程式賬戶),斷開與 Twitter 的連線,或釋出一條推文。

服務提供商“連線”框架

當您第一次點選示例應用程式中的“Twitter”連結時,您看到的是 Twitter 的連線狀態頁面。該頁面由 Spring Social 的 ConnectController 提供服務。ConnectController 是一個 Spring MVC 控制器,負責處理授權過程。對於 Twitter,這是一個 OAuth 1 授權流程。對於 OAuth 1,ConnectController 支援以下流程:

  • GET /connect/{provider ID} - 顯示連線狀態頁面。
  • POST /connect/{provider ID} - 啟動連線流程,從提供商請求一個請求令牌,然後重定向到提供商的授權頁面。
  • GET /connect/{provider ID}?oauth_token={request token}&oauth_verifier={verifier} - 處理授權後的回撥,用請求令牌和驗證器交換一個訪問令牌,並建立連線。
  • DELETE /connect/{provider ID} - 斷開與提供商的連線。

ConnectController 還支援 OAuth 2 的授權流程。當授權針對像 Facebook 這樣的基於 OAuth 2 的提供商時,ConnectController 的流程略有不同:

  • GET /connect/{provider ID} - 顯示連線狀態頁面。
  • POST /connect/{provider ID} - 啟動與提供商的授權,重定向到提供商的登入和/或授權頁面。
  • GET /connect/{provider ID}?code={code} - 處理來自提供商的授權回撥,用程式碼交換訪問令牌,並建立連線。
  • DELETE /connect/{provider ID} - 斷開與提供商的連線。

ConnectController 可以透過簡單地新增以下 <bean> 元素來配置到 Spring MVC 應用程式中。


<bean class="org.springframework.social.web.connect.ConnectController">
    <constructor-arg value="${application.url}" />
</bean>

如果您檢視示例應用程式中 ConnectController 的配置方式,您會發現它有一個 interceptors 屬性,注入了一個攔截器 bean 列表。連線攔截器允許您將自定義功能注入到連線流程中。其中一個攔截器 TweetAfterConnectInterceptor 負責在您連線到 Twitter 後釋出一條推文。(有關連線攔截器的更多資訊,請參閱 參考文件。)

當請求傳送到 ConnectController 時,它會與服務提供商類協同工作,以處理與服務的後臺互動。對於 Twitter,該提供商類是 TwitterServiceProvider,並在 Spring 中配置如下:


<bean class="org.springframework.social.twitter.connect.TwitterServiceProvider">
    <constructor-arg value="${twitter.appId}" />
    <constructor-arg value="${twitter.appSecret}" />
    <constructor-arg ref="connectionRepository" />
</bean>

TwitterServiceProvider,像 Spring 的所有服務提供商實現一樣,使用以下引數構建:

  • 應用程式的 ID 或消費者金鑰。
  • 應用程式的金鑰或消費者金鑰。
  • 一個用於持久化連線詳細資訊的連線儲存庫 bean 的引用。

當您在服務提供商處註冊應用程式時,您會獲得應用程式的消費者金鑰和金鑰。要註冊一個應用程式到 Twitter,請訪問 https://dev.twitter.com/apps/new 並填寫表單。完成後,Twitter 將返回一個顯示您的應用程式詳細資訊的頁面,包括消費者金鑰和消費者金鑰。

在這種情況下,應用程式的 Twitter 應用程式 ID 和金鑰被表示為佔位符變數,由屬性佔位符配置器解析。建議您將這些詳細資訊外部化,因為您在生產部署中很可能使用與測試和開發環境不同的 ID/金鑰對。

Spring 的每個服務提供商類都有一個提供商 ID(從其 getId() 方法返回,並且不同於其 Spring bean ID)。ConnectController 將使用該 ID,如 URL 路徑中指定的那樣,在建立連線時選擇它將與之合作的服務提供商。對於 TwitterServiceProvider,提供商 ID 是“twitter”。將此 ID 對映到 ConnectController 的請求對映,我們得到以下流程:

  • GET /connect/twitter - 顯示使用者與 Twitter 的連線狀態。
  • POST /connect/twitter - 從 Twitter 獲取一個請求令牌,然後重定向到 Twitter 的授權頁面。當您點選“連線到 Twitter”按鈕時,流程就是到這裡。
  • GET /connect/twitter?oauth_token={request token}&oauth_verifier={verifier} - 處理授權後的回撥,用請求令牌和驗證器交換一個訪問令牌,並建立連線。
  • DELETE /connect/twitter - 斷開與 Twitter 的連線。當您點選“斷開連線”按鈕時,就會發生這種情況。

建立連線後,將其儲存起來供將來使用非常重要,這樣您就不必反覆要求使用者重新授權您的應用程式。因此,TwitterServiceProvider 依賴於連線儲存庫來持久化連線資訊。Spring Social 提供了 JdbcConnectionRepository,它將連線詳細資訊持久化到關係資料庫中。JdbcConnectionRepository bean 的配置如下:


<bean id="connectionRepository" class="org.springframework.social.connect.jdbc.JdbcConnectionRepository">
    <constructor-arg ref="dataSource" />
    <constructor-arg ref="textEncryptor" />
</bean>

JdbcConnectionRepository 依賴於一個數據源,透過該資料來源它將訪問資料庫,以及一個 Spring Security 3.1 的 TextEncryptor 介面例項。它使用文字加密器在將連線憑據(例如訪問令牌和金鑰)儲存到資料庫時對其進行加密。作為一個示例應用程式,Spring Security 的加密需求相對較少,因此它與一個無操作文字加密器連線。


<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors" 
      factory-method="noOpText" />

(對於生產級別的加密,請考慮 Spring Security 的 Encryptors 靜態工廠類提供的其他加密器。)

處理連線

當您首次登入 Spring Social Showcase 時,它會顯示一個服務提供商列表,並表明您與其中任何一個都沒有連線。在與 Twitter 完成連線過程並返回到該頁面後,它會顯示已建立連線。

示例應用程式的 HomeController 透過呼叫每個提供商的 isConnected() 方法來確定與每個提供商的連線狀態。


for (ServiceProvider<?> serviceProvider : serviceProviders) {
	boolean connected = serviceProvider.isConnected(currentUser.getName());
	model.addAttribute(serviceProvider.getId() + "_status", connected ? "Yes" : "No");
}

如果給定賬戶與服務提供商之間存在一個或多個連線,isConnected() 方法將返回 true。

您還可以透過呼叫提供商的 getConnections() 方法來請求連線列表。


List<ServiceProviderConnection<TwitterApi>> connections = twitterProvider.getConnections(currentUser.getName());

從這些連線中的任何一個,您都可以檢索服務 API。例如,從第一個連接獲取 TwitterApi 的一個例項:


TwitterApi twitter = connections.get(0).getServiceApi();

使用該 TwitterApi 物件,您可以與 Twitter 進行互動,獲取時間線條目、釋出推文或執行 TwitterApi 介面中定義的任何其他操作。

這裡需要注意的關鍵一點是,應用程式程式碼在任何時候都不需要直接處理訪問令牌和金鑰即可與服務進行互動。服務提供商框架在幕後處理這些細節。

總結

Spring Social 1.0.0.M2 提供了一個服務提供商框架,大大簡化了應用程式在代表使用者獲取訪問服務的授權以及將使用者本地應用程式賬戶與他們在提供商處的賬戶連線方面的作用。為 Spring 應用程式新增連線功能涉及將服務提供商配置為 Spring 應用程式上下文中的一個 bean,並配置 Spring Social 的 ConnectController 來處理授權過程。有關使用 Spring Social 服務提供商框架的更多資訊,請參閱 參考文件

雖然 Spring Social 1.0.0.M2 只為 6 個提供商(Facebook、Twitter、LinkedIn、TripIt、GitHub 和 Gowalla)提供了服務提供商實現,但該框架易於擴充套件。在後續文章中,我將展示編寫自定義服務提供商實現所需的知識,使您能夠將 Spring Social 的連線支援用於您需要連線的任何提供商。

一如既往,我們非常樂意聽取您的反饋。我們鼓勵您在 論壇 中與我們合作,或透過提交增強請求到 問題跟蹤

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有