api postmain 鉴权_API鉴权

本文详细介绍了OneNET API的鉴权流程,包括鉴权参数Authorization的计算、签名算法、参数编码以及Python和Java的代码示例。鉴权通过访问资源、过期时间和签名方法等确保API访问的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API鉴权

为提高API访问安全性,OneNET API的鉴权参数Authorization作为Header参数存在。

Authorization计算的核心密钥为accessKey,用户需要使用核心密钥通过签名算法计算签名,与其他参数共同组成鉴权参数,然后将鉴权参数Authorization作为请求Header参数进行鉴权。

通过避免核心密钥在网络上直接传输,增加认证参数时效控制,增加密钥权限粒度控制(即将到来)等方式来提高鉴权安全性,最大限度保证访问安全。

1. API调用示例

(以“查询设备详情API”为例)

GET /devices/35****92 //35****92为平台随机分配的设备ID

Authorization: version=2018-10-31&res=products%2F123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw%3D

2. 鉴权参数算法

主要介绍Authorization的计算过程,Authorization用于接口调用,构成参数如下表所示:

名称类型是否必须参数说明参数示例

versionstring是参数组版本号,采用日期格式,目前支持"2018-10-31"2018-10-31

resstring是访问资源 resource

格式为:父资源类/父资源ID/子资源类/子资源ID

见表后的res使用场景说明products/123123

products/123123/devices/78329710

mqs/osndf09nand9f21390

etint是访问过期时间 expirationTime,采用unix时间

当一次访问参数中的et时间小于当前时间时,平台会认为访问参数过期从而拒绝该访问1537255523

表示:北京时间 2018-09-18 15:25:23

methodstring是签名方法 signatureMethod

支持md5、sha1、sha256sha256

signstring是签名结果字符串 signature

2.1 res使用场景说明

使用场景如下表:

场景res参数格式示例说明

API访问products/{pid}products/123123

设备连接products/{pid}/devices/{device_name}products/123123/devices/mydev需使用设备级密钥

2.2 sign签名算法

(1)参数sign的生成算法为:

sign = base64(hmac_(base64decode(accessKey), utf-8(StringForSignature)))

其中:

accessKey为OneNET为独立资源(例如,产品)分配的唯一访问密钥,其作为签名算法参数之一参与签名计算,为保证访问安全,请妥善保管。

accessKey参与计算前应先进行base64decode操作。

用于计算签名的字符串 StringForSignature的组成顺序按照参数名称进行字符串排序,以'/n'作为参数分隔,当前版本中按照如下顺序进行排序:et、method、res、version

(2)StringForSignature组成示例如下:

StringForSignature = et + '\n' + method + '\n' + res+ '\n' + version

注意:每个参数的格式均为key=value,但是仅参数中的value参与计算签名的字符串 StringForSignature的组成。

2.3 Authorization计算示例

(1)若Authorization参数如下:

et = 1537255523

method = sha1

res = products/123123

version = 2018-10-31

(2)则用于计算签名的字符串StringForSignature为(按照et、method、res、version的顺序)

StringForSignature = "1537255523" + "\n" + "sha1"+ "\n" + "products/123123"+ "\n" + "2018-10-31"

(3)计算出sign后,将每个参数均采用key=value的形式表示,并用'&'作为分隔符,示例如下:

version=2018-10-31&res=products/123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw=

3. 参数编码

Authorization中key=value的形式的value部分需要经过URL编码,需要进行编码的特殊符号如下:

序号

符号

编码

1

+

%2B

2

空格

%20

3

/

%2F

4

?

%3F

5

%

%25

6

#

%23

7

&

%26

8

=

%3D

编码后,上述示例中实际传输Authorization为:

version=2018-10-31&res=products%2F123123&et=1537255523&method=sha1&sign=ZjA1NzZlMmMxYzIOTg3MjBzNjYTI2MjA4Yw%3D

4. Authorization生成示例-Python

基于 python 生成 Authorization 代码示例如下:

!!!此处代码中的token即为Authorization。

import base64

import hmac

import time

from urllib.parse import quote

def token(id,access_key):

version = '2018-10-31'

res = 'products/%s' % id # 通过产品ID访问产品API

# 用户自定义token过期时间

et = str(int(time.time()) + 3600)

# 签名方法,支持md5、sha1、sha256

method = 'sha1'

# 对access_key进行decode

key = base64.b64decode(access_key)

# 计算sign

org = et + '\n' + method + '\n' + res + '\n' + version

sign_b = hmac.new(key=key, msg=org.encode(), digestmod=method)

sign = base64.b64encode(sign_b.digest()).decode()

# value 部分进行url编码,method/res/version值较为简单无需编码

sign = quote(sign, safe='')

res = quote(res, safe='')

# token参数拼接

token = 'version=%s&res=%s&et=%s&method=%s&sign=%s' % (version, res, et, method, sign)

return token

if __name__ == '__main__':

id = '123123'

access_key = 'KuF3NT/jUBJ62LNBB/A8XZA9CqS3Cu79B/ABmfA1UCw='

print(token(id,access_key))

5. Authorization生成示例-Java

基于 java 生成 Authorization 代码示例如下:

!!!此处代码中的token即为Authorization。

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.util.Base64;

public class Token{

public static String assembleToken(String version, String resourceName, String expirationTime, String signatureMethod, String accessKey)

throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException{

StringBuilder sb = new StringBuilder();

String res = URLEncoder.encode(resourceName, "UTF-8");

String sig = URLEncoder.encode(generatorSignature(version, resourceName, expirationTime

, accessKey, signatureMethod), "UTF-8");

sb.append("version=")

.append(version)

.append("&res=")

.append(res)

.append("&et=")

.append(expirationTime)

.append("&method=")

.append(signatureMethod)

.append("&sign=")

.append(sig);

return sb.toString();

}

public static String generatorSignature(String version, String resourceName, String expirationTime, String accessKey, String signatureMethod)

throws NoSuchAlgorithmException, InvalidKeyException{

String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version;

String signature;

byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod);

signature = Base64.getEncoder().encodeToString(bytes);

return signature;

}

public static byte[] HmacEncrypt(String data, String key, String signatureMethod)

throws NoSuchAlgorithmException, InvalidKeyException {

//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称

SecretKeySpec signinKey = null;

signinKey = new SecretKeySpec(Base64.getDecoder().decode(key),

"Hmac" + signatureMethod.toUpperCase());

//生成一个指定 Mac 算法 的 Mac 对象

Mac mac = null;

mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase());

//用给定密钥初始化 Mac 对象

mac.init(signinKey);

//完成 Mac 操作

return mac.doFinal(data.getBytes());

}

public enum SignatureMethod {

SHA1, MD5, SHA256;

}

public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException{

String version = "2018-10-31";

String resourceName = "products/123123";

String expirationTime = System.currentTimeMillis() / 1000 + 100 * 24 * 60 * 60 + "";

String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();

String accessKey = "KuF3NT/jUBJ62LNBB/A8XZA9CqS3Cu79B/ABmfA1UCw=";

String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);

System.out.println("Authorization:" + token);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值