原子能力鉴权SDK-JAVA最佳实践
更新时间:2026-07-13
概览
本 SDK 为原子能力服务提供鉴权支持。
原子能力服务(内容资源播放、联网搜索、闹钟提醒、会议纪要等)通过 SSE 流式接口对外暴露,调用方需在每个 HTTP 请求头中携带有效的 Token 和 设备指纹(Device Fingerprint),服务端据此对请求进行身份校验。
本 SDK 的职责是:
- 向鉴权服务器申请 Token
- 自动后台保活,保持 Token 持续有效(设备离线后,Token 及设备指纹失效)
- 提供 x-auth-token 和 x-device-fp 两个请求头所需的值
需求场景
当你需要调用原子能力 API(如音乐播放、联网搜索)时,HTTP 请求头中必须包含:
Plain Text
1x-auth-token: < token >
2x-device-fp: < deviceFp >
这两个值由本 SDK 统一管理。
调用方只需:
- 初始化 SDK,传入 appId、licenseId、userId、serverUrl
- 调用 getToken() 获取 token
- 调用 getDeviceFp() 获取设备指纹
- 将两个值写入请求头,即可正常调用原子能力接口
SDK 会在后台自动保活,无需业务层干预。
注意事项:
- 每次调用原子能力写入请求头前都需要重新调用 getToken() 及 getDeviceFp(),防止网络抖动等问题保活失败导致token失效。
- deviceId 不能为空:必须在 getToken() 前调用 setDeviceId(),否则返回 -1。
- 无需频繁创建 AuthSdk 实例:token 缓存是进程级共享的,复用同一个实例即可。
开发准备
- 参考 快速入门 文档开通服务、创建应用并获取 Appid 及 License Key
环境要求
- JDK 8 或以上
快速接入
1. 引入 SDK
将 SDK jar 包引入:
Plain Text
1<dependency>
2 <groupId>com.baidu.bce.rtc</groupId>
3 <artifactId>agent-token-auth-sdk</artifactId>
4 <version>1.0.2.1</version>
5</dependency>
2. 初始化
Plain Text
1AuthSdk sdk = new AuthSdk();
2
3// 设置设备唯一标识(MAC 地址、IMEI 或其他唯一字符串)
4sdk.setDeviceId("aa:bb:cc:dd:ee:ff");
5
6// 初始化,返回 0 表示成功
7int ret = sdk.init(appId, licenseId, userId, serverUrl);
8if (ret != AuthSdk.authOk()) {
9 // 参数有误,检查 appId/licenseId/userId/serverUrl 是否为空
10}
- setDeviceId 必须在 getToken() 之前调用。
3. 获取 Token 和设备指纹
Plain Text
1/**
2 * 将 token 和设备指纹放入业务请求头
3 * x-auth-token: {token}
4 * x-device-fp: {deviceFp}
5 */
6
7TokenResult result = sdk.getToken();
8if (result.isSuccess()) {
9 String token = result.token;
10 String deviceFp = sdk.getDeviceFp();
11} else {
12 // 根据 result.code 判断失败原因
13 log.error("getToken failed, code={}", result.code);
14}
getToken() 行为:
- 缓存有效时直接返回
- 缓存失效时自动申请新 token
4. 错误码说明
| code | 含义 | 处理建议 |
|---|---|---|
| > 0 | 成功,值为 token 长度 | 正常使用 token |
| -1 | 参数错误 | 检查 init 参数或 deviceId 是否为空 |
| -2 | 网络错误 | 检查网络连接和 serverUrl |
| -3 | 服务端业务错误 | 检查 appId/licenseId 是否有效 |
| -5 | 请求超时 | 检查网络或服务端状态 |
| -6 | 加密失败 | 环境异常,联系技术支持 |
| -7 | 响应 JSON 解析失败 | 服务端返回格式异常,联系技术支持 |
5. 程序退出时清理资源
Plain Text
1Runtime.getRuntime().addShutdownHook(new Thread(() -> {
2 sdk.cleanup();
3}));
4cleanup() 会停止保活机制并清除 token 缓存。
完整示例
Plain Text
1public class Demo {
2
3 private static final AuthSdk sdk = new AuthSdk();
4
5 public static void main(String[] args) {
6 sdk.setDeviceId("aa:bb:cc:dd:ee:ff");
7
8 int ret = sdk.init("your-app-id", "your-license-id", "your-user-id",
9 "http://your-server:8706");
10 if (ret != AuthSdk.authOk()) {
11 System.err.println("init failed: " + ret);
12 return;
13 }
14
15 TokenResult result = sdk.getToken();
16 if (!result.isSuccess()) {
17 System.err.println("getToken failed: " + result.code);
18 return;
19 }
20 String token = result.token;
21 String deviceFp = sdk.getDeviceFp();
22 System.out.println("token: " + token);
23 System.out.println("deviceFp: " + deviceFp);
24
25 Runtime.getRuntime().addShutdownHook(new Thread(sdk::cleanup));
26
27 // 业务逻辑...
28 }
29}
原子能力接口调用示例(以联网搜索为例)
- 具体原子能力功能请参见:原子能力API
- 获取 token 和 deviceFp 后,将它们写入请求头,调用原子能力 SSE 接口
Plain Text
1import okhttp3.*;
2import java.io.BufferedReader;
3import java.io.InputStreamReader;
4
5public class SearchExample {
6
7 private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
8 .readTimeout(60, java.util.concurrent.TimeUnit.SECONDS)
9 .build();
10
11 private static final String SEARCH_URL =
12 "https://gwgp-tdvpwojkegj.i.bdcloudapi.com/sse/v1/aiagent/chat/completions/search";
13
14 // 利用sdk获取的token及deviceFp加入请求头
15 public static void search(String token, String deviceFp, String query) throws Exception {
16
17 String body = "{\"messages\":[{\"contentItems\":[{\"type\":\"text\",\"text\":\""
18 + query + "\"}]}],\"response_format\":{\"text_stream\":true}}";
19
20 Request request = new Request.Builder()
21 .url(SEARCH_URL)
22 .addHeader("Content-Type", "application/json")
23 .addHeader("x-auth-token", token)
24 .addHeader("x-device-fp", deviceFp)
25 .post(RequestBody.create(body, MediaType.get("application/json")))
26 .build();
27
28 try (Response response = HTTP_CLIENT.newCall(request).execute()) {
29 if (!response.isSuccessful()) {
30 String errBody = response.body() != null ? response.body().string() : "";
31 throw new RuntimeException("HTTP error: " + response.code() + ", body=" + errBody);
32 }
33 BufferedReader reader = new BufferedReader(
34 new InputStreamReader(response.body().byteStream()));
35 String line;
36 while ((line = reader.readLine()) != null) {
37 if (line.startsWith("data:")) {
38 String data = line.substring(5).trim();
39 if ("[DONE]".equals(data)) {
40 break;
41 }
42 System.out.println("SSE event: " + data);
43 }
44 }
45 }
46 }
47}
评价此篇文章
