API 请求签名
如需访问即时通讯服务端 API(Server API),您需要对 API 请求签名,让即时通讯服务端能够验证应用程序的身份。
基本过程如下:
- App 后端需要在认证服务中预先设置 App Key 和 App Secret。
- 在调用 Server API 时,需要满足 HTTP 标头要求。 HTTP 标头中的数据签名
signature
需要使用 App Secret、随机数、时间戳进行计算。 - 即时通讯服务端收到请求后,会使用对应的 App Secret 进行同样的计算,并要求结果完全一致。
- 注意 App Secret 不可泄漏。请不要在网络中传输 App Secret,不要在不受信任的位置存放(浏览器等)。
获取 App Key / App Secret
获取应用的 App Key / App Secret 是使用即时通讯服务端 API 的必要条件。您可以前往控制台 App Key 页面进行查询。
您需要记录上图所示的应用 App Key 和 App Secret,在本教程中使用。在请求即时通讯服务端 API 接口时,每个 HTTP 请求中需要携带应用的 App Key 与数据签名。App Secret 用于计算数据签名,请注意不要泄露。
HTTP 标头
App Server 调用 API 接口时,每个 HTTP 请求中均需要携带以下的 HTTP 标头字段(HTTP Request Header),用于向即时通讯服务端提供身份认证信息:
默认名称 | 带 RC- 前缀 | 类型 | 说明 |
---|---|---|---|
App-Key | RC-App-Key | String | 控制台分配的 App Key。 |
Nonce | RC-Nonce | String | 随机数,不超过 18 个字符。 |
Timestamp | RC-Timestamp | String | 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的毫秒数。 |
Signature | RC-Signature | String | 数据签名。您需要参考下文的签名计算方法生成该字段的值。 |
(可选)在标头中添加 X-Request-ID 字段
我们建议在向融云发送的 Server API 标头中携带 X-Request-ID 字段,这有助于融云更高效地排查问题。融云的 Server SDK 已自动带上 X-Request-ID 字段,因此您无需额外生成。
Server SDK 链接:
如果您需要自行生成 X-Request-ID
(长度最大 36 位),可以参考下方示例:
Java 示例:
import java.util.UUID;
HttpURLConnection conn = getHttpURLConnection(config, uri);
conn.setRequestProperty("X-Request-ID", UUID.randomUUID().toString().replaceAll("\\-", ""));
PHP 示例:
private function create_guid()
{
$charid = strtoupper(md5(uniqid(mt_rand(), true)));
$uuid = substr($charid, 0, 8)
. substr($charid, 8, 4)
. substr($charid, 12, 4)
. substr($charid, 16, 4)
. substr($charid, 20, 12);
return strtolower($uuid);
}
$header = [
'RC-App-Key:' . $appKey,
'RC-Nonce:' . $nonce,
'RC-Timestamp:' . $timeStamp,
'RC-Signature:' . $sign,
'X-Request-ID:' . $this->create_guid()
];
Go 示例:
import "github.com/google/uuid"
// getSignature 本地生成签名
// Signature (数据签名)计算方法:将系统分配的 App Secret、Nonce (随机数)、
// Timestamp (时间戳)三个字符串按先后顺序拼接成一个字符串并进行 SHA1 哈希计算。如果调用的数据签名验证失败,接口调用会返回 HTTP 状态码 401。
func (rc RongCloud) getSignature() (nonce, timestamp, signature string) {
nonceInt := rand.Int()
nonce = strconv.Itoa(nonceInt)
timeInt64 := time.Now().Unix()
timestamp = strconv.FormatInt(timeInt64, 10)
h := sha1.New()
_, _ = io.WriteString(h, rc.appSecret+nonce+timestamp)
signature = fmt.Sprintf("%x", h.Sum(nil))
return
}
// fillHeader 在 Http Header 增加API签名
func (rc RongCloud) fillHeader(req *httplib.BeegoHTTPRequest) string {
requestId := uuid.New().String()
nonce, timestamp, signature := rc.getSignature()
req.Header("RC-App-Key", rc.appKey)
req.Header("RC-Timestamp", timestamp)
req.Header("RC-Nonce", nonce)
req.Header("RC-Signature", signature)
req.Header("Content-Type", "application/json")
req.Header("User-Agent", USERAGENT)
req.Header("RC-Request-Id", requestId)
return requestId
}
注意 请在每次请求中携带新生成的
X-Request-ID
,并做好记录。
签名计算方法
API 请求中需携 带该数据签名(Signature)字段,该字段值需要由 App 后端计算生成。步骤如下:
-
登录控制台,获取与应用 App Key 所对应的 App Secret。
-
将以下三个字符串按顺序(App Secret + Nonce + Timestamp)拼接成一个字符串,进行 SHA1 哈希计算。
- App Secret:应用 App Key 所对应的 App Secret。
- Nonce:随机数
- Timestamp:时间戳
即时通讯服务端在验证数据签名真实性后,会执行请求的动作。如果调用的数据签名验证失败,接口调用会返回 HTTP 状态码 401
。其他状态码请参见状态码表。
以下是计算数据签名的 PHP 代码示例:
// 重置随机数种子。
srand((double)microtime()*1000000);
$appSecret = 'your-own-app-secret'; // 请替换为您从开发者平台获取的 App Secret。
$nonce = rand(); // 获取随机数。
$timestamp = time()*1000; // 获取时间戳(毫秒)。
$signature = sha1($appSecret.$nonce.$timestamp);
HTTP 请求示例
以下 HTTP 请求示例展示了 API 请求中的 HTTP 标头字段。
POST /user/getToken.json HTTP/1.1
Host: api.rong-api.com
App-Key: your-own-app-key
Nonce: 14314
Timestamp: 1408710653000
Signature: 30be0bbca9c9b2e27578701e9fda2358a814c88f
Content-Type: application/x-www-form-urlencoded
Content-Length: 78
userId=jlk456j5&name=Ironman&portraitUri=http%3A%2F%2Fabc.com%2Fmyportrait.jpg