Unity | API鉴权用到的函数汇总

目录

一、HMAC-SHA1

二、UriEncode

三、Date

四、Content-MD5

五、参数操作

六、阿里云API鉴权


一、HMAC-SHA1

        使用 RFC 2104 中定义的 HMAC-SHA1 方法生成带有密钥的哈希值:

    private static string CalculateSignature(string secret, string data)
    {
        byte[] keyBytes = Encoding.UTF8.GetBytes(secret);
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);

        using (var hmacsha1 = new HMACSHA1(keyBytes))
        {
            byte[] hashBytes = hmacsha1.ComputeHash(dataBytes);

            // 将哈希值转换为十六进制字符串
            StringBuilder hexString = new StringBuilder(hashBytes.Length * 2);
            foreach (byte b in hashBytes)
            {
                hexString.AppendFormat("{0:x2}", b);
            }
            return hexString.ToString();
        }
    }

二、UriEncode

        按照RFC 3986进行 URI 编码:

private static string Rfc3986Encode(string value)
{
    // 使用 Uri.EscapeDataString 进行初步编码
    var encoded = Uri.EscapeDataString(value);

    // 根据 RFC 3986 的要求替换字符
    encoded = encoded.Replace("%20", "+");
    encoded = encoded.Replace("%21", "!");
    encoded = encoded.Replace("%27", "'");
    encoded = encoded.Replace("%28", "(");
    encoded = encoded.Replace("%29", ")");
    encoded = encoded.Replace("%7E", "~ ");

    return encoded;
}

三、Date

        当前 UTC 时间,以 ISO 8601 yyyyMMddTHHmmssZ 格式表示:

string date = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ");

        HTTP 1.1 协议中规定的 GMT 时间:(示例:Wed, 01 Mar 2006 12:00:00 GMT )

    public static string GetCurrentDateTimeInStandardFormat()
    {
        // 获取当前时间并转换到指定时区
        var dateTimeOffset = DateTimeOffset.UtcNow.ToOffset(TimeSpan.FromHours(8));

        // 将日期时间格式化为字符串
        var formattedDateTime = dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:sszzz");

        // 替换时区部分的冒号
        return formattedDateTime.Substring(0, 22) + formattedDateTime.Substring(23);
    }

四、Content-MD5

        RFC 1864 定义的请求体(Body) md5 摘要(128 位二进制表示,并使用 base64 编码):

    private static string CalculateMD5(byte[] data)
    {
        using (var md5 = MD5.Create())
        {
            byte[] hashBytes = md5.ComputeHash(data);
            return Convert.ToBase64String(hashBytes);
        }
    }

五、参数操作

        对 URL 中所有参数名、参数值单独 UriEncode,按参数名字母升序的顺序,依次将参数名、参数值用 = 及 & 拼接:

    private static string ConstructCanonicalQueryString(Dictionary<string, string> queryParams)
    {
        if (queryParams == null || queryParams.Count == 0)
            return "";

        var sortedQueryParams = queryParams.OrderBy(kvp => kvp.Key);
        var encodedQueryParams = sortedQueryParams.Select(kvp => $"{Rfc3986Encode(kvp.Key)}={Rfc3986Encode(kvp.Value)}");

        return string.Join("&", encodedQueryParams);
    }

六、阿里云API鉴权

        下方是阿里云上传文件API鉴权及请求示例(其实接入SDK更方便一些)。(阿里云上传文件后路径为https://桶名称.oss-cn-beijing.aliyuncs.com/文件夹/文件)

using UnityEngine;
using System.Collections;
using System.Security.Cryptography;
using System.Text;
using System;
using System.IO;
using UnityEngine.Networking;


public class AliYunManager : MonoBehaviour
{
    private const string OSS_HOST = "oss-cn-beijing.aliyuncs.com";//域名
    private const string BUCKET_NAME = "*****";//bucket名称
    private const string ACCESS_KEY_ID = "************";
    private const string ACCESS_KEY_SECRET = "**************";

    // Use this for initialization
    void Start()
    {
        UploadFileAsync("D:\\FCJProject\\YiDongYanFaBu\\StudentPartner\\StudentPartner\\Bundles\\StandaloneWindows\\DefaultPackage\\5.0.0\\1ba6bb9f41d66f71f7deb9d2d63b29e4.bundle", "/debug/PC/9.92.0");
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="imagePath">本地文件绝对路径</param>
    /// <param name="bucketPath">需要保存的文件在bucket上的相对路径,前后不需要加'/',也不需要加文件名</param>
    public void UploadFileAsync(string filePath, string bucketPath)
    {
        StartCoroutine(UploadFile(filePath, bucketPath));
    }

    IEnumerator UploadFile(string filePath, string bucketPath)
    {
        // Load the image from file
        byte[] imageBytes = File.ReadAllBytes(filePath);

        string fileName = Path.GetFileName(filePath);
        string bucketFilePath = "/" + bucketPath + "/" + fileName;
        string url = "https://" + BUCKET_NAME + "." + OSS_HOST + bucketFilePath;
        string contentMD5 = "";// ToMD5(imageBytes);
        string contentType = "application/octet-stream";
        string utcGMT = DateTime.UtcNow.ToString("r");
        string canonicalizedOSSHeaders = "";
        string canonicalizedResource = "/" + BUCKET_NAME +bucketFilePath;
        string authorization = GetAuthorization("PUT", contentMD5, contentType, utcGMT, canonicalizedOSSHeaders, canonicalizedResource);
        Debug.Log("Authorization: " + authorization);
        Debug.Log("url: " + url);
        //Debug.Log("contentMD5: " + contentMD5);
        // Create UnityWebRequest
        UnityWebRequest request = new UnityWebRequest(url, "PUT");
        //request.uploadHandler = new UploadHandlerRaw(imageData);
        request.downloadHandler = new DownloadHandlerBuffer();
        // Set headers
        request.SetRequestHeader("Content-Length", imageBytes.Length.ToString());
        request.SetRequestHeader("Content-Type", contentType);
        request.SetRequestHeader("Host", BUCKET_NAME + "." + OSS_HOST);
        request.SetRequestHeader("Date", utcGMT);
        request.SetRequestHeader("Authorization", authorization);

        // Set the body of the request
        UploadHandlerRaw uploadHandler = new UploadHandlerRaw(imageBytes);
        uploadHandler.contentType = contentType;

        request.uploadHandler = uploadHandler;

        // Send the request and wait for a response
        yield return request.SendWebRequest();

        if (request.result != UnityWebRequest.Result.Success)
        {
            Debug.LogError($"Error: {request.error}");
            Debug.LogError($"Response Code: {request.responseCode}");
            Debug.LogError($"Response Text: {request.downloadHandler.text}");

        }
        else
            Debug.Log(request.downloadHandler.text);
    }

    private string GetAuthorization(
        string method, string contentMD5, string contentType,
        string utcGMT, string canonicalizedOSSHeaders, string canonicalizedResource)
    {
        string data = method + "\n"
            + contentMD5 + "\n"
            + contentType + "\n"
            + utcGMT + "\n"
            + canonicalizedOSSHeaders
            + canonicalizedResource;

        Debug.Log("data:"+ data);
        string signature = ToHMACSHA1_Base64(ACCESS_KEY_SECRET, data);
        string authorization = "OSS " + ACCESS_KEY_ID + ":" + signature;

        return authorization;
    }

    private static string ToHMACSHA1_Base64(string key, string data)
    {
        using (HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key)))
        {
            byte[] dataBuffer = Encoding.UTF8.GetBytes(data);
            byte[] hashBytes = hmacsha1.ComputeHash(dataBuffer);

            string result = Convert.ToBase64String(hashBytes);
            return result;
        }
    }

    private static string ToMD5(byte[] data)
    {
        using (MD5 md5Hash = MD5.Create())
        {
            byte[] hashBytes = md5Hash.ComputeHash(data);
            Debug.Log(hashBytes.Length);

            return Convert.ToBase64String(hashBytes);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755501.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MacBook 中 Java使用testcontainers报错

环境 MacBook 问题 Java代码中使用testcontainers启动报错 ERROR org.testcontainers.dockerclient.DockerClientProviderStrategy - Could not find a valid Docker environment. Please check configuration. Attempted configurations were:UnixSocketClientProviderStr…

鸿蒙NEXT

[中国&#xff0c;东莞&#xff0c;2024年6月24日] 华为开发者大会&#xff08;HDC&#xff09;正式开幕&#xff0c;带来全新的 HarmonyOS NEXT、盘古大模型5.0等最创新成果&#xff0c;持续为消费者和开发者带来创新体验。 HarmonyOS NEXT 鸿蒙生态 星河璀璨 鸿蒙生态设备数…

亨廷顿(Huntington)方法-名额分配

前言 20世纪初&#xff0c;美国人口普查局局长约瑟夫A亨廷顿&#xff08;Joseph A. Hill&#xff09;和数学家爱德华V亨廷顿&#xff08;Edward V. Huntington&#xff09;在研究议会议席分配问题时&#xff0c;提出了一种基于数学原理的算法。该算法通过计算每个州的人口比例&…

【数组】- 螺旋矩阵 II

1. 对应力扣题目连接 螺旋矩阵 II 题目简述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。如图&#xff1a; 2. 实现案例代码 public class SpiralMatrix {public static…

重磅更新-UniApp自定义字体可视化设计

重磅更新-UniApp自定义字体可视化设计。 DIY可视化为了适配不同APP需要&#xff0c;支持用户自定义字体&#xff0c;自定义字体后&#xff0c;设计出来的界面更多样化&#xff0c;不再是单一字体效果。用户可以使用第三方字体加入设计&#xff0c;在设计的时候选择上自己的字体…

MyBatis第一节

目录 1. 简介2. 配置3. doing3.1 创建一个表3.2 打开IDEA&#xff0c;创建一个maven项目3.3 导入依赖的jar包3.4 创建entity3.5 编写mapper映射文件(编写SQL)3.6 编写主配置文件3.7 编写接口3.8 测试 参考链接 1. 简介 它是一款半自动的ORM持久层框架&#xff0c;具有较高的SQ…

【技术指南】稳压器(电压调节器):原理、类型及其实际用用案例

电压调节器&#xff08;稳压器&#xff09;是一种电子器件或电路&#xff0c;用于控制电路中的电压水平&#xff0c;以确保在电源电压波动或负载变化时&#xff0c;输出电压能够保持在设定的稳定水平。它们通常用于各种电子设备和电源系统中&#xff0c;以提供稳定的电压供应。…

AI绘画 Stable Diffusion【特效文字】:火焰特效艺术字,轻松搞定特效生成!

大家好&#xff0c;我是画画的小强 今天我们继续艺术字系列的分享&#xff0c;艺术字的玩法很多&#xff0c;今天给大家带来的是火焰特效艺术字的制作。我们先来看火焰特效艺术字的效果图。 一. 火焰特效文字的制作方法 【第一步】&#xff1a;制作底图 这里制作底图使用白底…

HarmonyOS Next开发学习手册——通过startAbilityByType拉起垂类应用

使用场景 开发者可通过特定的业务类型如导航、金融等&#xff0c;调用startAbilityByType接口拉起对应的垂域面板&#xff0c;该面板将展示目标方接入的垂域应用&#xff0c;由用户选择打开指定应用以实现相应的垂类意图。垂域面板为调用方提供统一的安全、可信的目标方应用&a…

数据结构与算法笔记:高级篇 - 搜索:如何用 A* 搜索算法实现游戏中的寻路功能?

概述 魔兽世界、仙剑奇侠传这类 MMRPG 游戏&#xff0c;不知道你玩过没有&#xff1f;在这些游戏中&#xff0c;有一个非常重要的功能&#xff0c;那就是任务角色自动寻路。当任务处于游戏地图中的某个位置时&#xff0c;我们用鼠标点击另外一个相对较远的位置&#xff0c;任务…

Flutter循序渐进==>Dart之类型、控制流和循环

导言 磨刀不误砍柴工&#xff0c;想搞好Flutter&#xff0c;先学好Flutter&#xff0c;还是本着我学Python的方法&#xff0c;先从数据类型、控制流和循环开始&#xff0c;这是每一种编程语言必用的。编程语言是相通的&#xff0c;基本精通一种后&#xff0c;学其它的就变得很…

网络配置(IP、NETMASK、GATEWAY、DNS、DHCP) <持续更新中>

参考&#xff1a; 初学Linux之网络配置(IP、NETMASK、GATEWAY、DNS、DHCP)-CSDN博客【学习笔记】网关 & 路由_网关和路由-CSDN博客【学习笔记】计算机网络 IP地址与MAC地址_根据mac分配ip-CSDN博客【学习笔记】TCP 和 UDP 协议_tcp 发送 syn 应答没有syn ack-CSDN博客 一…

Kafka 位移

Consumer位移管理机制 将Consumer的位移数据作为一条条普通的Kafka消息&#xff0c;提交到__consumer_offsets中。可以这么说&#xff0c;__consumer_offsets的主要作用是保存Kafka消费者的位移信息。使用Kafka主题来保存位移。 消息格式 位移主题就是普通的Kafka主题。也是…

计算机组成原理:海明校验

在上图中&#xff0c;对绿色的7比特数据进行海明校验&#xff0c;需要添加紫色的4比特校验位&#xff0c;总共是蓝色的11比特。紫色的校验位pi分布于蓝色的hi的1, 2, 4, 8, 16, 32, 64位&#xff0c;是2i-1位。绿色的数据位bi分布于剩下的位。 在下图中&#xff0c;b1位于h3&a…

高频面试题基本总结回顾2(含笔试高频算法整理)

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

kubernetes给指定用户分配调用k8s的api权限

文章目录 概要利用RBAC添加角色权限使用shell命令创建角色权限使用配置文件创建角色权限 调用k8s的api获取k8s账户的token 小结 概要 使用kubernetes部署项目时&#xff0c;有些特殊场景&#xff0c;我们需要在自己创建的pod里面调用k8s的api来管理k8s&#xff0c;但是需要使用…

论文笔记:Spatial-Temporal Interval Aware Sequential POI Recommendation

ICDE 2022 1 intro 1.1 背景 空间&#xff08;Spatial&#xff09;和时间&#xff08;Temporal&#xff09;信息是序列 POI 推荐中两个重要且相辅相成的因素。 空间因素&#xff08;如地理距离间隔&#xff09;可以在用户的历史轨迹呈现空间分簇现象时&#xff0c;细粒度刻画…

Elasticsearch 聚合查询简介

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

Pytest集成Allure生成测试报告

# 运行并输出报告在Report文件夹下 查看生成的allure报告 1. 生成allure报告&#xff1a;pycharm terminal中输入命令&#xff1a;产生报告文件夹 pytest -s --alluredir../report 2. pycharm terminal中输入命令&#xff1a;查看生成的allure报告 allure serve ../report …

[数据集][目标检测]婴儿状态睡觉哭泣检测数据集VOC+YOLO格式7109张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;7109 标注数量(xml文件个数)&#xff1a;7109 标注数量(txt文件个数)&#xff1a;7109 标注…