跳到主要内容

API 请求签名

如需访问即时通讯服务端 API(Server API),您需要对 API 请求签名,让即时通讯服务端能够验证应用程序的身份。

基本过程如下:

  1. App 后端需要在认证服务中预先设置 App Key 和 App Secret。
  2. 在调用 Server API 时,需要满足 HTTP 标头要求。 HTTP 标头中的数据签名 signature 需要使用 App Secret、随机数、时间戳进行计算。
  3. 即时通讯服务端收到请求后,会使用对应的 App Secret 进行同样的计算,并要求结果完全一致。
  4. 注意 App Secret 不可泄漏。请不要在网络中传输 App Secret,不要在不受信任的位置存放(浏览器等)。

获取 App Key / App Secret

获取应用的 App Key / App Secret 是使用即时通讯服务端 API 的必要条件。您可以前往控制台 App Key 页面进行查询。

(width=800)

您需要记录上图所示的应用 App Key 和 App Secret,在本教程中使用。在请求即时通讯服务端 API 接口时,每个 HTTP 请求中需要携带应用的 App Key 与数据签名。App Secret 用于计算数据签名,请注意不要泄露。

HTTP 标头

App Server 调用 API 接口时,每个 HTTP 请求中均需要携带以下的 HTTP 标头字段(HTTP Request Header),用于向即时通讯服务端提供身份认证信息:

默认名称RC-前缀类型说明
App-KeyRC-App-KeyString控制台分配的 App Key。
NonceRC-NonceString随机数,不超过 18 个字符。
TimestampRC-TimestampString时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在的毫秒数。
SignatureRC-SignatureString数据签名。您需要参考下文的签名计算方法生成该字段的值。

(可选)在标头中添加 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 后端计算生成。步骤如下:

  1. 登录控制台,获取与应用 App Key 所对应的 App Secret。

  2. 将以下三个字符串按顺序(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