1. 简介

在本教程中,我们将介绍 ScribeJava 这个库。

ScribeJava 是一个用于 Java 的轻量级 OAuth 客户端库,旨在简化 OAuth 认证流程。

它的核心优势在于:

  • 开箱即用地支持主流 OAuth 1.0 和 OAuth 2.0 接口(如 Google、GitHub、Twitter 等)
  • ✅ 如果你需要对接一个非标准接口,ScribeJava 也提供了扩展类让你自定义实现
  • ✅ 支持多种 HTTP 客户端,包括:
    • Async Http Client
    • OkHttp
    • Apache HttpComponents HttpClient

此外,该库是线程安全的,并且兼容 Java 7,因此可以在较老的项目环境中使用。

2. Maven 依赖

ScribeJava 的模块划分清晰,分为核心模块和接口模块:

标准用法(包含常见接口支持)

<dependency>
    <groupId>com.github.scribejava</groupId>
    <artifactId>scribejava-apis</artifactId>
    <version>最新版本</version>
</dependency>

仅使用核心功能(不包含预定义接口)

<dependency>
    <groupId>com.github.scribejava</groupId>
    <artifactId>scribejava-core</artifactId>
    <version>最新版本</version>
</dependency>

📌 最新版本请查阅 Maven Repository

3. OAuthService 类

OAuthService 是整个库的核心抽象类,它封装了完成 OAuth 流程所需的所有参数。

根据协议版本的不同,我们分别使用:

  • OAuth 1.0 → Oauth10Service
  • OAuth 2.0 → Oauth20Service

构建 Service 实例的方式如下:

OAuthService service = new ServiceBuilder("api_key")
  .apiSecret("api_secret")
  .scope("scope")
  .callback("callback")
  .build(GoogleApi20.instance());

其中:

  • api_keyapi_secret 是授权服务器分配的凭证
  • scope 是请求权限范围(视接口而定)
  • callback 是认证完成后跳转的回调地址

⚠️ 不同协议下,某些参数可能不是必须的。

最后调用 .build() 方法并传入对应的 API 实例即可。

3.1. 自定义 HTTP 客户端

你可以指定使用的 HTTP 客户端:

ServiceBuilder builder = new ServiceBuilder("api_key")
  .httpClient(new OkHttpHttpClient());

当然,前提是你已添加对应依赖:

<dependency>
    <groupId>com.github.scribejava</groupId>
    <artifactId>scribejava-httpclient-okhttp</artifactId>
    <version>最新版本</version>
</dependency>

📌 查看更多客户端支持:Maven Repository

3.2. 调试模式

调试时可以开启 Debug 输出:

ServiceBuilder builder = new ServiceBuilder("api_key")
  .debug();

默认会输出到 System.out。如果需要重定向输出流,也可以这样写:

FileOutputStream debugFile = new FileOutputStream("debug");

ServiceBuilder builder = new ServiceBuilder("api_key")
  .debug()
  .debugStream(debugFile);

4. OAuth 1.0 流程

以 Twitter 接口为例演示 OAuth 1.0 认证流程:

首先创建 Oauth10Service 实例:

OAuth10aService service = new ServiceBuilder("api_key")
  .apiSecret("api_secret")
  .build(TwitterApi.instance());

接着获取 request token 并生成授权链接:

OAuth1RequestToken requestToken = service.getRequestToken();
String authUrl = service.getAuthorizationUrl(requestToken);

用户访问该 URL 后,会被重定向回你的回调地址,从中提取 oauthVerifier 参数。

然后换取 access token:

OAuth1AccessToken accessToken = service.getAccessToken(requestToken, oauthVerifier);

最后构造请求并签名执行:

OAuthRequest request = new OAuthRequest(Verb.GET, 
    "https://api.twitter.com/1.1/account/verify_credentials.json");
service.signRequest(accessToken, request);

Response response = service.execute(request);

最终返回的是一个 Response 对象,你可以从中读取响应内容。

5. OAuth 2.0 流程

OAuth 2.0 流程与 1.0 类似,以 Google 接口为例说明:

创建 OAuth20Service 实例并获取授权 URL:

OAuth20Service service = new ServiceBuilder("api_key")
  .apiSecret("api_secret")
  .scope("https://www.googleapis.com/auth/userinfo.email")
  .callback("http://localhost:8080/auth")
  .build(GoogleApi20.instance());

String authUrl = service.getAuthorizationUrl();

用户授权后,会跳转到你配置的 callback 地址,并携带 code 参数。

通过 code 获取 access token:

OAuth2AccessToken accessToken = service.getAccessToken(code);

OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json");
service.signRequest(accessToken, request);

Response response = service.execute(request);

最终你可以使用 accessToken 来发起受保护资源的请求。

6. 自定义接口支持

如果你要对接的接口不在 ScribeJava 预置列表中,可以自行扩展。

只需继承 DefaultApi10DefaultApi20 并实现关键方法即可。

例如,假设我们有一个基于密码模式的 OAuth 2.0 授权服务器:

public class MyApi extends DefaultApi20 {

    public MyApi() {}

    private static class InstanceHolder {
        private static final MyApi INSTANCE = new MyApi();
    }

    public static MyApi instance() {
        return InstanceHolder.INSTANCE;
    }

    @Override
    public String getAccessTokenEndpoint() {
        return "http://localhost:8080/oauth/token";
    }

    @Override
    protected String getAuthorizationBaseUrl() {
        return null;
    }
}

然后就可以像这样使用:

OAuth20Service service = new ServiceBuilder("baeldung_api_key")
  .apiSecret("baeldung_api_secret")
  .scope("read write")
  .build(MyApi.instance());

OAuth2AccessToken token = service.getAccessTokenPasswordGrant(username, password);

OAuthRequest request = new OAuthRequest(Verb.GET, "http://localhost:8080/me");
service.signRequest(token, request);
Response response = service.execute(request);

这种方式简单粗暴,特别适合快速集成私有或非标准 OAuth 接口。

7. 总结

本文介绍了 ScribeJava 中最常用的几个类和典型使用方式:

✅ 如何使用 OAuth 1.0 和 OAuth 2.0 处理第三方认证
✅ 如何配置不同的 HTTP 客户端
✅ 如何启用调试模式
✅ 如何自定义自己的 OAuth 接口实现

所有示例代码均可在 GitHub 仓库 找到。


原始标题:Guide to ScribeJava | Baeldung