当前位置: 移动技术网 > IT编程>开发语言>.net > .netcore2.1 JS-SDK 从后台获取微信签名,实现自定义分享标题、描述、图片

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

2019年05月15日  | 移动技术网IT编程  | 我要评论

金士顿32gu盘修复,安邦董事长吴小晖情人,陈以庭

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

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

 

 

  • 后端签名算法实现 ,参考腾讯开发者文档

  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;
        }

        /// <summary>
        /// 获取access_token
        /// </summary>
        /// <returns></returns>
        private accesstokenresponse getaccesstoken()
        {
           
            string url = _tencentapi + "/token?grant_type=client_credential&appid=" + _appid + "&secret=" + _appsecret;
            var response = apiclient.getjson<accesstokenresponse>(url);
            return response;
        }

        /// <summary>
        /// 获取jsapiticket
        /// </summary>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        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<accessticketresponse>(url);

            return response?.ticket;
        }

        /// <summary>
        /// 获取签名
        /// </summary>
        /// <param name="jsapi_ticket"></param>
        /// <param name="noncestr">随机字符串(必须与wx.config中的noncestr相同)</param>
        /// <param name="timestamp">时间戳(必须与wx.config中的timestamp相同)</param>
        /// <param name="url">当前网页的url,不包含#及其后面部分(必须是调用js接口页面的完整url)</param>
        /// <returns></returns>
        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());
        }
       
        /// <summary>
        /// sha1加密签名
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        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
    {
        /// <summary>
        /// 返回access_token值,有效期7200秒
        /// </summary>
        public string access_token { get; set; }
        /// <summary>
        /// 过期时间,单位小时
        /// </summary>
        public datetime expire_out { get; set; }


    }

    public class accessticketresponse : baseresponse
    {
        /// <summary>
        /// 返回ticket票据,有效期7200秒
        /// </summary>
        public string ticket { get; set; }

    }
  public class baseresponse
    {
        /// <summary>
        /// 过期时间,单位秒
        /// </summary>
        public string expire_in { get; set; }
        /// <summary>
        /// 错误代码
        /// </summary>
        public int32 errcode { get; set; }
        /// <summary>
        /// 错误信息描述
        /// </summary>
        public string errmsg { get; set; }
    }
  • 创建生成签名的时间戳和随机串
 /// <summary>
        /// 获取微信js-jdk时间戳
        /// </summary>
        /// <returns></returns>
        public static string gettimestamp()
        {
            timespan ts = datetime.utcnow - new datetime(1970, 1, 1, 0, 0, 0);

            return convert.toint64(ts.totalseconds).tostring();
        }
     
        /// <summary>
        /// js-jdk 创建随机字符串
        /// </summary>
        /// <returns></returns>
        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. 移动端分享时,不能本地测试,需要发布到外网测试,否则报签名错误
  3. 生成的签名,可以实用校验工具校验是否正确。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网