热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

.netcore2.1JSSDK从后台获取微信签名,实现自定义分享标题、描述、图片

最近项目移动端需要实现微信自定义分享功能,包含分享自定义标题、描述等。首先到公众号的后台,功能设置里面,添加将要被分享的域名,如图  后端签名算法实现,参考腾讯开发者文档https

  最近项目移动端需要实现微信自定义分享功能,包含分享自定义标题、描述等。

  • 首先到公众号的后台,功能设置里面,添加将要被分享的域名,如图

 

.netcore2.1  JS-SDK  从后台获取微信签名,实现自定义分享标题、描述、图片

 

  • 后端签名算法实现 ,参考腾讯开发者文档https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

  jsapi_ticket

  生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

  生成签名步骤,获取AccessToken-》获取JsApiTicket-》生成签名

  appsettings配置文件添加配置

 "Api": {
    "JSJDKBaseApi": "https://api.weixin.qq.com/cgi-bin"
  },
  "JSJDK": {
    "AppId": "***",
    "Secret": "****"
  }
  • 创建签名公用类
 public class JSSDKSignHelper
    {
        private static AccessTokenResponse singleAccessToken;
        
        private  string _tencentApi { get; set; }
        private  string _appid { get; set; }
        private  string _appSecret { get; set; }

        public  JSSDKSignHelper(IConfiguration config)
        {
           
            _tencentApi = config["Api:JSJDKBaseApi"]; 
            _appid = config["JSJDK:AppId"];
            _appSecret = config["JSJDK:Secret"];
        }

        public string GetAccessTokenSingle(out bool isNewObj)
        {
            isNewObj = false;
            if (singleAccessToken != null && (singleAccessToken.expire_out > DateTime.Now.AddHours(2)))
            {
                return singleAccessToken.access_token;
            }
            else
            {
                var respOnse= GetAccessToken();
                if (response.errcode == 0)
                {
                    response.expire_out = DateTime.Now.AddHours(expireHour);
                    singleAccessToken = response;
                    isNewObj = true;
                    return response?.access_token;
                }
            }
            return null;
        }

        /// 
        /// 获取access_token
        /// 
        /// 
        private AccessTokenResponse GetAccessToken()
        {
           
            string url = _tencentApi + "/token?grant_type=client_credential&appid=" + _appid + "&secret=" + _appSecret;
            var respOnse= ApiClient.GetJson(url);
            return response;
        }

        /// 
        /// 获取JsApiTicket
        /// 
        /// 
        /// 
        public  string GetJsApiTicket(string accessToken)
        {
            if (string.IsNullOrWhiteSpace(accessToken))
            {
                return null;
            }
            string url = _tencentApi + $"/ticket/getticket?type=jsapi&access_token={accessToken}";

            var respOnse= ApiClient.GetJson(url);

            return response?.ticket;
        }

        /// 
        /// 获取签名
        /// 
        /// 
        /// 随机字符串(必须与wx.config中的nonceStr相同)
        /// 时间戳(必须与wx.config中的timestamp相同)
        /// 当前网页的URL,不包含#及其后面部分(必须是调用JS接口页面的完整URL)
        /// 
        public string  GetSignature(string jsapi_ticket, string noncestr, string timestamp, string url)
        {
            if (string.IsNullOrEmpty(jsapi_ticket) || string.IsNullOrEmpty(noncestr) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(url))
                return null;
            var string1Builder = new StringBuilder();
            string1Builder.Append("jsapi_ticket=").Append(jsapi_ticket).Append("&")
                          .Append("nOncestr=").Append(noncestr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
             return Sha1Sign(string1Builder.ToString());
        }
       
        /// 
        /// Sha1加密签名
        /// 
        /// 
        /// 
        public string Sha1Sign(string str)
        {
            SHA1 sha1 = new SHA1CryptoServiceProvider();
            byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str);
            byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);
            string signature = BitConverter.ToString(bytes_sha1_out);
            signature = signature.Replace("-", "").ToLower();
            return signature;
        }

    }
  • 签名定义的Model
public class AccessTokenResponse: BaseResponse
    {
        /// 
        /// 返回access_token值,有效期7200秒
        /// 
        public string access_token { get; set; }
        /// 
        /// 过期时间,单位小时
        /// 
        public DateTime expire_out { get; set; }


    }

    public class AccessTicketResponse : BaseResponse
    {
        /// 
        /// 返回Ticket票据,有效期7200秒
        /// 
        public string ticket { get; set; }

    }
  public class BaseResponse
    {
        /// 
        /// 过期时间,单位秒
        /// 
        public string expire_in { get; set; }
        /// 
        /// 错误代码
        /// 
        public Int32 errcode { get; set; }
        /// 
        /// 错误信息描述
        /// 
        public string errmsg { get; set; }
    }
  • 创建生成签名的时间戳和随机串
 /// 
        /// 获取微信JS-JDK时间戳
        /// 
        /// 
        public static string GetTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);

            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
     
        /// 
        /// JS-JDK 创建随机字符串
        /// 
        /// 
        public static string CreatenNonce_str()
        {
            Random r = new Random();
            var sb = new StringBuilder();
            var length = strs.Length;
            for (int i = 0; i <15; i++)
            {
                sb.Append(strs[r.Next(length - 1)]);
            }
            return sb.ToString();
        }
  • Action中实际调用
        [HttpPost]
        [Route("GetSignature")]
        public string GetSignature(string url= "http://www.sina.cn/")
        {
            try
            {
                if (string.IsNullOrEmpty(url)) return "url不能为空";
                string _jsTicket = null, _signature = null;
                string _accessToken = _jsSignHelper.GetAccessTokenSingle(out bool isNewObj);
                WxConfigModel model = new WxConfigModel();
                model.AppId = appId;
                model.TimeStamp = MyUtil.GetTimeStamp();
                model.NonceStr = MyUtil.CreatenNonce_str();
                if (isNewObj|| _wxConfigModel.Signature==null)
                {

                    _jsTicket = _jsSignHelper.GetJsApiTicket(_accessToken);
                    _signature = _jsSignHelper.GetSignature(_jsTicket, model.NonceStr, model.TimeStamp, url);
                    model.jsTicket = _jsTicket;
                    model.Signature = _signature;
                    _wxConfigModel = model;
                }
                return JsonConvert.SerializeObject(model);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }    

  注意:

  1. 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
  2. 移动端分享时,不能本地测试,需要发布到外网测试,否则报签名错误
    1. .netcore2.1  JS-SDK  从后台获取微信签名,实现自定义分享标题、描述、图片
  3. 生成的签名,可以实用校验工具校验是否正确。https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign

推荐阅读
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 安装mysqlclient失败解决办法
    本文介绍了在MAC系统中,使用django使用mysql数据库报错的解决办法。通过源码安装mysqlclient或将mysql_config添加到系统环境变量中,可以解决安装mysqlclient失败的问题。同时,还介绍了查看mysql安装路径和使配置文件生效的方法。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • Python如何调用类里面的方法
    本文介绍了在Python中调用同一个类中的方法需要加上self参数,并且规范写法要求每个函数的第一个参数都为self。同时还介绍了如何调用另一个类中的方法。详细内容请阅读剩余部分。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了在Linux下安装Perl的步骤,并提供了一个简单的Perl程序示例。同时,还展示了运行该程序的结果。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文介绍了关于apache、phpmyadmin、mysql、php、emacs、path等知识点,以及如何搭建php环境。文章提供了详细的安装步骤和所需软件列表,希望能帮助读者解决与LAMP相关的技术问题。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
author-avatar
小曾
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有