APP端
this.$http
.post(`/uniCloudRegister`, {
clientInfo:JSON.stringify(uni.getSystemInfoSync())
})
.then(res =>{
uni.stopPullDownRefresh()
uni.hideNavigationBarLoading()
console.info(res)
}).catch(err => {
console.error(err)
uni.stopPullDownRefresh()
uni.hideNavigationBarLoading()
})
后台接口 UserController:ApiController
ConstantsConstants//业务系统登录后才需要联登到 uniCloud,所以不需要在注册时执行,而是单独给出了注册功能的接口
[HttpPost]
[Route("uniCloudRegister")]
public async Task<HttpResponseMessage> uniCloudRegister([FromBody] UniClient client)
{
HttpResponseMessage response = null;
try
{
//此为验证当前系统token并转为 user类的工具,这里就不给出详细示例了
var ui = JwtHelper.AnalysisToken(HttpContext.Current.Request);
//见 Utils
string uniAppUserName = Utils.GetExternalUid(ui);
string nonce = Utils.GetNonce();
// 获取当前时间戳(精确到毫秒)
long timestamp = Utils.GetNowTimeStamp();
Dictionary<string, string> paramsDictionary = new Dictionary<string, string>
{
{ "externalUid", uniAppUserName},
{ "nickname", ui.Name},
};
//签名算法见 Utils
string signature = Utils.GetSignature(paramsDictionary, nonce, timestamp);
//client.clientInfo 为JSON.stringify(uni.getSystemInfoSync()) 这里再转回json对象
var cliInfo = JsonConvert.DeserializeObject<JObject>(client.clientInfo);
Dictionary<string, object> param = new Dictionary<string, object>();
param.Add("clientInfo", cliInfo);
param.Add("uniIdToken", "");
param.Add("params", paramsDictionary);
// 将对象序列化为JSON字符串
string jsonContent = JsonConvert.SerializeObject(param);
Dictionary<string, string> headers = new Dictionary<string, string>()
{
{"uni-id-nonce",nonce },
{"uni-id-timestamp",timestamp + ""},
{"uni-id-signature",signature}
};
var res = await HttpHelper.SendPostAsync(Constants.PushRegister, jsonContent, headers);
if (res.Count > 0)
{
response = Request.CreateResponse(System.Net.HttpStatusCode.OK, res);
}
else
{
response = Request.CreateResponse(System.Net.HttpStatusCode.BadRequest, "error");
}
}
catch (Exception ex)
{
response = Request.CreateErrorResponse(System.Net.HttpStatusCode.InternalServerError, "error");
}
return response;
}
Constants
//uniapp 外部系统联登 https://doc.dcloud.net.cn/uniCloud/uni-id/cloud-object.html#external
public static readonly string PushUrl = "you url";
//uniapp 注册
public static readonly string PushRegister = PushUrl + "externalRegister";
//uniapp 登录
public static readonly string PushLogin = PushUrl + "externalLogin";
//uniapp 修改信息
public static readonly string PushUpdateUser = PushUrl + "updateUserInfoByExternal ";
UniClient
public class UniClient
{
public string clientInfo { get; set; }
public string uniIdToken { get; set; }
}
Utils
/// <summary>
/// 根据用户信息 获取uniapp的uid, 这个就根据自己的业务来处理
/// </summary>
/// <param name="ui"></param>
/// <returns></returns>
public static string GetExternalUid(UserInfo ui)
{
//分别为角色ID、 用户ID和用户账号
return ui.Role + "_" + ui.Id + "_" + ui.userName;
}
//获取随机字符串 这里其实可以固定返回一组字符串
public static string GetNonce()
{
return GenerateRandomStringLinq(8);
}
private static string GenerateRandomStringLinq(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
/// <summary>
/// uniapp 鉴权签名算法
/// </summary>
/// <param name="parameters"></param>
/// <param name="nonce"></param>
/// <param name="timestamp"></param>
/// <returns></returns>
public static string GetSignature(Dictionary<string, string> parameters, string nonce, long timestamp)
{
string paramsStr = GetParamsString(parameters);
using (HMACSHA256 hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(Constants.RequestAuthSecret + nonce)))
{
string message = timestamp.ToString() + paramsStr;
byte[] messageBytes = Encoding.UTF8.GetBytes(message);
byte[] hashBytes = hmacSha256.ComputeHash(messageBytes);
return ByteArrayToHexString(hashBytes).ToUpper();
}
}
/// <summary>
/// 获取当前时间戳 单位毫秒
/// </summary>
/// <returns></returns>
public static long GetNowTimeStamp()
{
return (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
}
private static string GetParamsString(Dictionary<string, string> parameters)
{
var keys = new List<string>(parameters.Keys);
keys.Sort();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < keys.Count; i++)
{
if (i != 0)
{
sb.Append("&");
}
sb.Append(keys[i]).Append("=").Append(parameters[keys[i]]);
}
return sb.ToString();
}
private static string ByteArrayToHexString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in bytes)
{
string hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
HttpHelper
/// <summary>
/// POST异步请求
///
/// </summary>
/// <param name="url">请求url</param>
/// <param name="jsonContent"></param>
/// <param name="headers"></param>
/// <returns></returns>
// 发送POST请求的函数
public static async Task<JObject> SendPostAsync(string url, string jsonContent, Dictionary<string, string> headers = null)
{
using (var client = new HttpClient())
{
var jsonObject = new JObject();
if (headers != null)
{
foreach (KeyValuePair<string, string> header in headers)
{
client.DefaultRequestHeaders.Add(header.Key, header.Value);
}
}
try
{
// 创建一个HttpContent对象,用于发送JSON数据
var httpContent = new StringContent(jsonContent, Encoding.UTF8, "application/json");
// 发送POST请求
HttpResponseMessage response = await client.PostAsync(url, httpContent);
// 确保HTTP请求成功
//response.EnsureSuccessStatusCode();
// 读取响应内容
var responseBody = await response.Content.ReadAsStringAsync();
//LoggerHelper.Info("请求:" + url + ",参数:" + jsonContent + ",结果:" + responseBody);
jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
}
catch (HttpRequestException e)
{
LoggerHelper.Error("请求失败!",e);
}
return jsonObject;
}
}
tips: 出现了 “clientInfo.uniPlatform” is required. 是没有传参数clientInfo
参考 官方文档