小程序开发系列(六)获取群信息

来源:互联网 发布:mac用flash 编辑:程序博客网 时间:2024/06/05 06:07

小程序最近发布了新功能,转发到群中的页面,再点击的时候可以获取群信息,比如群ID,那要如何实现呢?

1.在页面中开启“转发”功能

代码如下

 onLoad: function () {    wx.showShareMenu({      withShareTicket: true    });  },

2.在页面中设置“转发”参数

 //转发  onShareAppMessage: function () {    return {      title: '转发XXXX',      path: '/pages/retrospect/retrospect',      success: function (res) {        // 转发成功        var shareTickets = res.shareTickets;        var shareTicket = shareTickets;        wx.getShareInfo({          shareTicket: shareTicket,          success: function (res) {            console.log('success');            console.log(res);            //console.log(res);            wx.showToast({              title: '转发成功',              duration: 5000            })          },          fail: function (res) {            console.log('fail');            console.log(res);            wx.showToast({              title: 'fail:' + res.errMsg,              duration: 5000            })          }        });      },      fail: function (res) {        // 转发失败      }    }  }
注:在转发的时候可以获取到shareTicket,使用shareTicket调用wx.getShareInfo可以得到群信息,具体实现请参看后面的代码。

3.响应用户从转发的群中进入

app.js的onLaunch在小程序启动时会触发一次,且直到小程序销毁。app.js中的onShow在小程序显示的时候会触发,只要显示就触发,所以会触发多次。在onLaunch和onShow函数中的参数options可以拿到shareTicket,具体要如何触发需要结合自身场景,简单的示例代码如下,

App({  onLaunch: function (options) {    //this.checkLogin(options.shareTicket);    this.globalData.shareInfo=null;  },  onShow: function (options) {    this.checkLogin(options.shareTicket);  },  checkLogin: function (shareTicket) {    var that = this;    wx.checkSession({      success: function () {        if (!that.globalData.session) {          that.login(shareTicket);        };      },      fail: function () {        that.login(shareTicket);      }    })  },  //登录  login: function (shareTicket) {    var that = this    wx.login({      success: function (r) {        if (r.code) {          that.decodeSession(r.code, shareTicket);        }        wx.getUserInfo({          success: function (res) {            that.globalData.userInfo = res.userInfo;          }        })      }    })  },  //解密session信息  decodeSession: function (code, shareTicket) {    var that = this;    wx.request({      url: urls.WeiXin.FetchSessionInfo,//向后端发起换取session_key请求的URL      data: {        code: code      },      success: function (re) {        if (re.data.Status == 0) {          that.globalData.session = {            openid: re.data.Data.openid,            key: re.data.Data.session_key          };          if (shareTicket) {            that.getShareInfo(shareTicket);          }        }        else {          that.globalData.session = null;        }      }    })  },  //获取群信息  getShareInfo: function (shareTicket) {    var that = this;    wx.getShareInfo({      shareTicket: shareTicket,      success: function (res) {        wx.request({          url: urls.WeiXin.Encrypt,//向后端发起解密请求的URL          data: {            encryptData: res.encryptedData,            encryptSessionKey: that.globalData.session.key,            iv: res.iv          },          success: function (re) {            var msg='';            if (re.data.Status == 0) {              that.globalData.shareInfo =JSON.parse(re.data.Data);              msg = '来自群转发';            }            else {              that.globalData.session = null;              msg=re.data.Message;            }            wx.showToast({              title: msg,              duration: 5000            })          }        })              },      fail: function (res) {        console.log('fail');        console.log(res.errMsg);        wx.showToast({          title: 'fail:' + res.errMsg,          duration: 5000        })      }    });  },  globalData: {    userInfo: null,    session: null,    shareInfo: null  }})
注:

(1).必须要在执行wx.login登录后才能拿到群信息,否则getShareInfo会提示"you need login".

(2).登录得到的code拿到后端去换取session_key和openId,后面换取的数据是加密的需要进行解密才能得到session_key和openId.

(3).getShareInfo拿到的数据是加密的数据,需要传到后端去解密,解密时需要encryptData、session_key和iv。其中encryptData和iv在getShareInfo的res中可以拿到,session_key在登录的时候可以换取得到。

4.换取session_key

后端使用asp.net的MVC中的C层,即控制器来处理。具体可以参看网络中的相关文章。

session控制器的代码如下

 /// <summary>    /// 微信会话    /// </summary>    public class WXSessionController : ApiController    {        #region FetchSessionInfo        /// <summary>        /// 获取SESSION信息        /// </summary>        /// <returns></returns>        [HttpGet]        public BaseDataPackage<WXSessionInfoPackage> FetchSessionInfo(string code)        {            var result = new BaseDataPackage<WXSessionInfoPackage>();            var data = WXSession.FetchSessionInfo(code);            result.Data = data;            if (data != null && data.IsOK())            {                result.Status = StatusCode.OK;                result.Message = "OK";            }            else            {                result.Status = StatusCode.FAIL;                result.Message = data.errmsg;            }            return result;        }        #endregion    }
 public class BaseDataPackage<T>    {        public BaseDataPackage();        public int Status { get; set; }        public string Message { get; set; }        public T Data { get; set; }        public bool IsOK(){return Status==0;}    }
//    // 摘要:    //     WebApi请求的状态码    public class StatusCode    {        //        // 摘要:        //     请求成功        public const int OK = 0;        //        // 摘要:        //     失败        public const int FAIL = 1;        //        // 摘要:        //     异常        public const int EXCEPTION = 2;}
 public class WXSessionInfoPackage : WXPackageBase    {        public string openid { get; set; }        public string session_key { get; set; }    }
    public class WXPackageBase    {        #region 属性        public int errcode { get; set; } = StatusCode.OK;        public string errmsg { get; set; }        #endregion        #region IsOK        public bool IsOK()        {            if (errcode == StatusCode.OK)            {                return true;            }            return false;        }        #endregion    }

  public class WXSession    {/// <summary>        /// code 换取 session_key、openid        /// </summary>        public const string SNS_JSCODE2SESSION = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";        #region FetchSessionInfo        public static WXSessionInfoPackage FetchSessionInfo(string code)        {    //AppId和AppSecret从微信的小程序页面中复制下来即可            string url = string.Format(SNS_JSCODE2SESSION,AppId, AppSecret, code);            var sessionInfo = HttpHelper.Get<WXSessionInfoPackage>(url);            if (sessionInfo != null)            {                sessionInfo.session_key = Encrypt(sessionInfo.session_key);                sessionInfo.openid = Encrypt(sessionInfo.openid);            }            return sessionInfo;        }        #endregion        #region Encrypt        /// <summary>        /// 对session的数据加密        /// </summary>        /// <param name="data"></param>        /// <returns></returns>        public static string Encrypt(string data)        {            if (string.IsNullOrEmpty(data))            {                return data;            }            var buff = Encoding.UTF8.GetBytes(data);            var dest = Convert.ToBase64String(buff);            return dest;        }        #endregion        #region Descrypt        /// <summary>        /// 对session的数据解密        /// </summary>        /// <param name="data"></param>        /// <returns></returns>        public static string Descrypt(string data)        {            if (string.IsNullOrEmpty(data))            {                return data;            }            var buff = Convert.FromBase64String(data);            var dest = Encoding.UTF8.GetString(buff);            return dest;        }        #endregion    }


注:为了数据的安全,获取到的session_key和openid作了加密处理,即Encrypt方法,Encrypt的实现依需要而不同,比如可以使用简单的base64加密等。为此需要有一个对应的解密方法Decrypt.

附HttpHelper.Get方法

 /// <summary>    /// HTTP帮助类    /// </summary>    public class HttpHelper    {        #region Get        /// <summary>        /// 执行基本的命令方法,以Get方式        /// </summary>        /// <param name="apiurl">请求的URL</param>        /// <param name="headers">请求头的key-value字典</param>        /// <param name="needReturnHeader">true:返回响应头,数据将以{Header:headerDict,Data:responseStr}的json格式返回,        /// 其中headerDict为响应头的字典格式的数据,responseStr为请求返回的响应字符串.false:直接返回响应数据</param>        /// <returns></returns>        public static string Get(string apiurl, Dictionary<string, string> headers = null, bool needReturnHeader = false)        {            WebRequest request = WebRequest.Create(apiurl);            request.Method = RequestMethod.GET;            if (headers != null)            {                foreach (var keyValue in headers)                {                    request.Headers.Add(keyValue.Key, keyValue.Value);                }            }            WebResponse response = request.GetResponse();            Stream stream = response.GetResponseStream();            Encoding encode = Encoding.UTF8;            StreamReader reader = new StreamReader(stream, encode);            string resultJson = reader.ReadToEnd();            if (needReturnHeader)            {                Dictionary<string, string> headerDict = new Dictionary<string, string>();                foreach (var key in response.Headers.AllKeys)                {                    headerDict.Add(key, response.Headers[key]);                }                var temp = new                {                    Header = headerDict,                    Data = resultJson                };                return temp.ToJson();            }            else            {                return resultJson;            }        }#endregion}
微信开发工具拿到的session_key


5.解密群信息

   public class WXEncrypt    {        #region Decrypt        /// <summary>        /// 解密数据        /// </summary>        /// <param name="encryptStrOfBase64">base64加密后的字符串,如果没有进行URL编码直接传输,加号在传输时会变成空格,
此时建议替换成%2B传输.wx.request会默认进行URL编码。</param>        /// <param name="encryptSessionKey">加密后的sessionKey</param>        /// <param name="iv"></param>        /// <returns></returns>        public static string Decrypt(string encryptStrOfBase64, string encryptSessionKey, string iv)        {            var sessionKey = WXSession.Descrypt(encryptSessionKey);            encryptStrOfBase64 = encryptStrOfBase64.Replace("%2B", "+");            if (sessionKey.Length % 3 == 1)            {                sessionKey += "==";            }            else if (sessionKey.Length % 3 == 2)            {                sessionKey += "=";            }            var Key = Convert.FromBase64String(sessionKey);            var Iv = Convert.FromBase64String(iv);            byte[] dataByte = AesEncryptHelper.Decrypt(encryptStrOfBase64, Iv, Key);            string dataStr = Encoding.UTF8.GetString(dataByte);            return dataStr;        }        #endregion

   /// <summary>    /// AES算法    /// </summary>    public class AesEncryptHelper    {        #region Decrypt        /// <summary>        /// 解密        /// </summary>        /// <param name="encryptStrOfBase64"></param>        /// <param name="Iv"></param>        /// <param name="Key"></param>        /// <returns></returns>        public static byte[] Decrypt(String encryptStrOfBase64, byte[] Iv, byte[] Key)        {            RijndaelManaged aes = new RijndaelManaged();            aes.KeySize = 256;            aes.BlockSize = 128;            aes.Mode = CipherMode.CBC;            aes.Padding = PaddingMode.None;            aes.Key = Key;            aes.IV = Iv;            var decrypt = aes.CreateDecryptor(aes.Key, aes.IV);            byte[] xBuff = null;            using (var ms = new MemoryStream())            {                using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))                {                    byte[] xXml = Convert.FromBase64String(encryptStrOfBase64);                    byte[] msg = new byte[xXml.Length + 32 - xXml.Length % 32];                    Array.Copy(xXml, msg, xXml.Length);                    cs.Write(xXml, 0, xXml.Length);                }                xBuff = decode(ms.ToArray());            }            return xBuff;        }        #region decode        private static byte[] decode(byte[] decrypted)        {            int pad = (int)decrypted[decrypted.Length - 1];            if (pad < 1 || pad > 32)            {                pad = 0;            }            byte[] res = new byte[decrypted.Length - pad];            Array.Copy(decrypted, 0, res, 0, decrypted.Length - pad);            return res;        }        #endregion        #endregion}
解密结果

转载请注明出处。






0 0
原创粉丝点击