阿里云微服务消息队列(MQTT For IoT)C# 获取Token示例Demo
概述
微消息队列MQTT通过Token鉴权模式向MQTT客户端提供有时效性的临时访问权限。通过MQTT Token服务可以给本地账号系统管理的用户颁发临时的访问凭证,并限制访问权限,以实现对单一客户端,单一资源的细粒度权限控制。目前官方已经给出了Java获取Token的Demo,下面给出基于C#获取Token的实现,然后使用PostMan工具测试,用户可以基于PostMan工具生成其它语言获取Token的方法。
相关参考
1、API官方说明地址;
2、参考Java Demo;
C# Code实现
1、Nuget 安装:Newtonsoft,处理Json对象使用;
2、完整的Code Sample
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json.Linq;
namespace MQTTTokenDemo
{
class Program
{
static void Main(string[] args)
{
// 参数解释:https://help.aliyun.com/document_detail/54276.html?spm=a2c4g.11186623.6.572.632e2584wtKkVY
string resources = "Demodd/AAA";
string instanceId = "post-cn-mp9********";
string accessKey = "********";
string secretkey = "********";
long expireTime = 10000000L;
applyToken(resources, instanceId, accessKey, secretkey, expireTime);
}
/// <summary>
/// 请求获取Token
/// </summary>
/// <param name="resources">资源名称,即 MQTT Topic,多个 Topic 以逗号(,)分隔</param>
/// <param name="instanceId">MQTT 实例 ID,一定要和客户端实际使用的实例 ID 匹配</param>
/// <param name="accessKey">当前请求使用的账号的 AccessKeyId</param>
/// <param name="secretkey">当前请求使用的账号的 AccessSecretId</param>
/// <param name="expireTime">Token 失效的毫秒时间戳</param>
public static void applyToken(string resources, string instanceId, string accessKey, string secretkey, long expireTime)
{
string apiUrl = "https://mqauth.aliyuncs.com/token/apply";
Dictionary<string, string> paramDic = new Dictionary<string, string>();
paramDic.Add("resources", resources);
paramDic.Add("actions", "R,W");
paramDic.Add("serviceName", "mq");
paramDic.Add("expireTime", (((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000) + expireTime).ToString());
paramDic.Add("instanceId", instanceId);
string signature = doHttpSignature(paramDic, secretkey);
paramDic.Add("proxyType", "MQTT");
paramDic.Add("accessKey", accessKey);
paramDic.Add("signature", System.Web.HttpUtility.UrlEncode(signature)); // 注意:此处务必对求得的signature进行urlencode处理,否则可能会因为不同时间求取的signature中可能包含特殊字符而出现请求407报错
//Console.WriteLine(sendRequestToGetToken(apiUrl, paramDic));
JObject json = JObject.Parse(sendRequestToGetToken(apiUrl, paramDic));
Console.WriteLine("Token: " + json["tokenData"].ToString());
Console.ReadKey();
}
/// <summary>
/// 计算签名signature
/// </summary>
/// <param name="paramDic"> 参数字典 </param>
/// <param name="secretKey"> accessSecret </param>
/// <returns> 返回签名 </returns>
public static string doHttpSignature(Dictionary<string, string> paramDic, string secretKey)
{
List<string> paramList = new List<string>();
foreach (KeyValuePair<string, string> kvp in paramDic)
{
paramList.Add(kvp.Key + "=" + kvp.Value);
}
paramList.Sort();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < paramList.Count; i++)
{
if (i > 0)
{
stringBuilder.Append("&");
}
stringBuilder.Append(paramList[i]);
}
HMACSHA1 hmacKey = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey));
string signature = Convert.ToBase64String(hmacKey.ComputeHash(Encoding.UTF8.GetBytes(stringBuilder.ToString())));
return signature;
}
/// <summary>
/// 发送请求以获取token
/// </summary>
/// <param name="url"> url </param>
/// <param name="parameters"> 请求的参数 </param>
/// <param name="encoding"> 请求参数的编码方式 </param>
/// <returns> 返回响应结果 </returns>
public static string sendRequestToGetToken(string url, Dictionary<string, string> parameters)
{
//设置请求接口
var request = (HttpWebRequest)WebRequest.Create(url);
byte[] data = null;
StringBuilder buffer = new StringBuilder();
// 设置请求参数
if (!(parameters == null || parameters.Count == 0))
{
int i = 0;
foreach (string key in parameters.Keys)
{
if (i > 0)
{
buffer.AppendFormat("&{0}={1}", key, parameters[key]);
}
else
{
buffer.AppendFormat("{0}={1}", key, parameters[key]);
}
i++;
}
}
data = Encoding.UTF8.GetBytes(buffer.ToString());
//请求方式
request.Method = "POST";
//请求头参数设置
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
WebResponse response;
try
{
response = request.GetResponse();
}
catch (WebException ex)
{
response = ex.Response;
}
//转字符串
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return responseString;
}
}
}
3、测试运行结果
Post Man工具使用
1、具体的测试参数可以在上面Code的parameters对象中获取
2、请求参数设置
3、一键生成其它语言Demo
注意: signature参数还是需要使用者基于自己的开发语言自行参考Java或C# Demo实现。
参考链接
lmq-demo
C# POST请求demo,contentType 格式:application/x-www-form-urlencoded




