幸运蛋蛋pc开奖
这篇文章主要介绍了.Net之微信小程序获取用户UnionID的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言:

在实际项目开发中我们经常会遇到账号统一的问题,如何在不同端或者是不同的登录方式下保证同一个会员或者用户账号唯一(便于用户信息的管理)。这段时间就有一个这样的需求,之前有个客户做了一个微信小程序商城(店主端的),然后现在又要做一个会员?#20309;?#31471;的小程序商场。首先之前用户登?#35745;?#35777;?#38469;?#20351;用微信openid来做的唯一标识,而现在客户需求是要做到用户在会员端小程序跳转到到店主端小程序假如之前该用户微信是在店主端审核通过的用户则不需要在进行资料提交审核操作,直接登录。所以,所以我们使用了UnionID来进行关联,如下是我们现在项目的基本流程(画的丑莫见怪)。

说说UnionID机制:

如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 UnionID 是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

官方UnionID机制详细说明:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html

微信开放平台绑定小程序流程:

登录微信开放平台— 管理中心 — 小程序 — 绑定小程序(直接使用微信官方图)

微信小程序获取UnoinID的两种方式

调用接口wx.getUserInfo,从解密数据(encryptedData)中获取 UnionID(推荐使用):

推荐使用原因?#20309;?#38656;关注微信公众号即可获取到UnionID。

调用接口wx.getUserInfo前提:用户允许授权获取用户信息!

开发者后台校验与解密开放数据:

微信为了保证用户信息,把用户通过wx.getUserInfo接口获取到的相关信息进行了?#29992;堋<用?#26041;式对称?#29992;埽?#21518;面会提到),首先我们需要通过微信小程序登录流程获取到用户的session_key(会话密钥),然后我们可?#21592;?#33719;取到的会话密钥使用缓存存起来,在通过用户授权获取用户相关信息,如下是用户授权成功获取到的用户信息:

基本流程图如下:

(encryptedData)?#29992;?#25968;据解密算法:

开发者如需要获取数据,需要对接口返回的?#29992;?#25968;据(encryptedData)进行对?#24179;?#23494;。 解密算法如下:

    对?#24179;?#23494;使用的算法为 AES-128-CBC,数据采用PKCS#7填充。 对?#24179;?#23494;的目标密文为 Base64_Decode(encryptedData)。 对?#24179;?#23494;秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。 对?#24179;?#23494;算法初始向量 为Base64_Decode(iv),其中iv由数据接口返回

很遗憾的是微信居然没有为我们大.Net提供解密算法demo,实属让人不算,最后自己根据网上的资料还是配上了符合微信对称?#29992;?#30340;解密算法。

代码实现:

首先关于session_key(会话密钥)的获取,请看下面的wx.login+code2Session 方式

调用接口wx.getUserInfo获取encryptedData(?#29992;?#25968;据)和iv(初始向量):

// 用户已经授权
wx.getUserInfo({
success: function(res) {
console.log(res);
var userInfo = res.userInfo //用户基本信息
let sessionKey = wx.getStorageSync("session_key");//临时会话密钥,通过小程序登录流程获取到的
//请求.net webapi解密接口
wx.request({
 url: 'https://www.xxxtest.com/api/User_oAuth/DecryptSensitiveData',
data: {
sessionKey:sessionKey,
encryptedData:res.encryptedData,
iv:res.iv
},
 header: {
'content-type': 'application/json' // 默?#29616;?},
success (res) {
//解密返回过来的UnionID
console.log(res.data)
}
})
}
})
})

.Net WebApi 解密数据接口:

/// <summary>
  /// 解密微信对称?#29992;?#25968;据,获取用户联合运营编号
  /// </summary>
  /// <param name="sessionKey">临时会话秘钥</param>
  /// <param name="encryptedData">微信用户?#29992;?#25968;据</param>
  /// <param name="iv">解密初始向量</param>
  /// <returns></returns>
  [HttpGet]
  public IHttpActionResult DecryptSensitiveData(string sessionKey,string encryptedData,string iv)
  {
   try
   {
    var getUnionId=DecryptByAesBytes(encryptedData, sessionKey, iv);

    return Json(new { code =1, msg="解密成功",result= getUnionId });
   }
   catch (Exception ex)
   {
    return Json(new { code = 0, msg = "解密失败,原因:"+ex.Message });
   }
  }

  #region AES对?#24179;?#23494;
  /// <summary>
  /// AES解密
  /// </summary>
  /// <param name="encryptedData">待解密的字节数组</param>
  /// <param name="sessionKey">解密密钥字节数组</param>
  /// <param name="iv">IV初始化向量字节数组</param>
  /// <param name="cipher">运算模式</param>
  /// <param name="padding">填充模式</param>
  /// <returns></returns>
  private static string DecryptByAesBytes(string encryptedData, string sessionKey, string iv)
  {
   try
   {
    //非空验证
    if (!string.IsNullOrWhiteSpace(encryptedData) && !string.IsNullOrWhiteSpace(sessionKey) && !string.IsNullOrWhiteSpace(iv))
    {
     var decryptBytes = Convert.FromBase64String(encryptedData.Replace(' ', '+'));
     var keyBytes = Convert.FromBase64String(sessionKey.Replace(' ', '+'));
     var ivBytes = Convert.FromBase64String(iv.Replace(' ', '+'));

     var aes = new AesCryptoServiceProvider
     {
      Key = keyBytes,
      IV = ivBytes,
      Mode = CipherMode.CBC,
      Padding = PaddingMode.PKCS7
     };

     var outputBytes = aes.CreateDecryptor().TransformFinalBlock(decryptBytes, 0, decryptBytes.Length);

     var decryptResult = Encoding.UTF8.GetString(outputBytes);
     dynamic decryptData = JsonConvert.DeserializeObject(decryptResult, new { unionid = "" }.GetType());
     JJHL.Utility.Loghelper.WriteLog("AES对?#24179;?#23494;结果为:" + decryptResult);
     return decryptData.unionid;
    }
    else
    {
     return "";
    }
   }
   catch (Exception e)
   {
    JJHL.Utility.Loghelper.WriteLog("AES对?#24179;?#23494;失败原因:" + e.Message);
    return "";
   }
  }

  #endregion

所遇异常:参数使用Convert.FromBase64String转化时,提示“Base-64字符数组的无效长?#21462;?的问题:

原因:?#29992;?#21442;数中的"+"通过地址栏传过来时,后台会解析为空格(遇到的概?#26102;?#36739;小)。

解决:最好的做法是 使用encryptedData.Replace("+", "%2B")先将空格编码,然后再作为参数传给另一页面传递,这样页面在提取参数时才会将“%2B”解码为加号.但这儿为了简化,将空格直接还原为"+"或者是直接在后台将空格替换为“+”encryptedData.Replace(' ', '+');

直接通过wx.login+code2Session获取到该用户 UnionID:

其实这个方式就是实现了小程序的登录流程,微信官方详细说明:

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html</p><p>&#20248;&#28857;?#20309;?#38656;&#29992;&#25143;&#25480;&#26435;。</p><p>&#21069;&#25552;:&#29992;&#25143;&#38656;&#35201;&#20851;&#27880;&#35813;&#24494;&#20449;&#20844;&#20247;&#21495;。</p><p>&#23567;&#31243;&#24207;&#31471;&#35843;&#29992;&#25509;&#21475;wx.login&#33719;&#21462;code&#20973;&#35777;,&#22312;&#36890;&#36807;&#35831;&#27714;auth.code2Session&#25509;&#21475;&#33719;&#21462;&#29992;&#25143;&#20449;&#24687;(UnionID,openid,session_key&#20250;&#35805;&#23494;&#38053;)&#20004;&#31181;&#26041;&#24335;:</p><p>1.&#30452;&#25509;&#36890;&#36807;wx.login&#35831;&#27714;&#21040;code&#20973;&#35777;&#21518;,&#22312;&#35831;&#27714;&#35813;&#22320;&#22336;&#33719;&#21462;&#29992;&#25143;&#20449;&#24687;:</p><p><code>GET:https://api.weixin.qq.com/sns/jscode2session&#63;appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code</code></p><p>&#35814;&#32454;&#35828;&#26126;&#35831;&#30475;&#24494;&#20449;&#23448;&#26041;&#25991;&#26723;(&#20195;&#30721;&#30053;):https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

2.通过请求wx.login获取code凭证,在向.net webapi后端请求code2Session接口:

原因:因为我们需要对获取的用户信息做相关业务逻辑处理。

微信小程序端代码:

[code]//promise机制放回成功数据 
resolve(res.data); 
} else 
{ reject('error'); } 
}, fail: function(res) 
{ 
reject(res); 
wx.showToast({ title: '系统错误' }) 
}, complete: () => { } //complete接口执行后的回调函数,无论成功失败都会调用 
}) } else 
{ 
reject("error"); 
}}
})})}[/code

.Net WebApi 请求用户信息接口:

/// <summary>
  /// 获取用户信息
  /// </summary>
  /// <param name="code">信息数据code凭证</param>
  /// <returns></returns>
  [HttpGet]
  public IHttpActionResult GetUserInfo(string code)
  {
   string AppSecret = "小程序秘钥";
   string AppId = "应用程序标识";

   try
   {
    //请求目标地址和参数(authorization_code授权类型,此处只需填写 authorization_code)
    string OauthUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + AppId + "&secret=" + AppSecret + "&js_code=" + code + "&grant_type=authorization_code";//序列化解析数据
    var Result = HttpGet(OauthUrl);

    return Json(new { openid = Result.openid, errcode = Result.errcode, UnionID = Result.unionid, session_key = Result.session_key });
   }
   catch (Exception ex)
   {

    return Json(new { errcode = 1, msg = "获取用户信息失败" + ex.Message });
   }
  }

  /// <summary>
  /// 请求code2Session接口获取用户信息
  /// </summary>
  /// <param name="requestDataAndUrl">目标地址和参数</param>
  /// <returns></returns>
  public WxOauthModle HttpGet(string requestDataAndUrl)
  {
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestDataAndUrl);
   request.Method = "GET";
   request.ContentType = "text/html;charset=UTF-8";
   HttpWebResponse response = (HttpWebResponse)request.GetResponse();
   Stream myResponseStream = response.GetResponseStream();
   StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
   string retString = myStreamReader.ReadToEnd();
   myStreamReader.Close();
   myResponseStream.Close();

   return JsonConvert.DeserializeObject<WxOauthModle>(retString);
  }

  public class WxOauthModle
  {
   /// <summary>
   /// 用户唯一标识
   /// </summary>
   public string openid { get; set; }

   /// <summary>
   /// 会话秘钥
   /// </summary>
   public string session_key { get; set; }

   /// <summary>
   /// 联立编号
   /// </summary>
   public string unionid { get; set; }

   /// <summary>
   /// 错误码
   /// </summary>
   public int errcode { get; set; }

   /// <summary>
   /// 错误信息
   /// </summary>
   public string errmsg { get; set; }
  }

关于微信网页开发通过UnionID机制解决用户在不同公众号,或在公众号、移动应用之间帐号统一问题:

详情说明请点击:http://www.asjcu.tw/article/168982.htm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持爱安网。

最新资讯
腾讯高管解读三季度财报:游戏开发能力被消费者认可

腾讯高管解读三季度财

财报显示,腾讯第三季度营收972亿元,同比增长20.6%;第三季
16寸屏苹果MacBook Pro终于发布:屏幕大了 键盘改进

16寸屏苹果MacBook Pr

苹果公司刚刚正式推出了16英寸MacBook Pro,没有发布会,
16寸苹果MacBook Pro上手:它大了 也强了

16寸苹果MacBook Pro

这产品是2016年MacBook Pro大?#30446;?#20043;后的第一次重大升
一图看懂腾讯三季度财报:营收972亿元 同比增长21%

一图看懂腾讯三季度财

财报显示,腾讯第三季度营收972亿元,同比增长20.6%;第三季
阿里启动香港IPO!马云:逐步减少在蚂蚁金服经济利益

阿里启动香港IPO!马云:

招股书内容显示,阿里巴巴在提交港交所的上市申请文件中
阿里巴?#25512;?#21160;香港IPO 发售新发行5亿股普通股新股

阿里巴?#25512;?#21160;香港IPO

阿里巴?#22270;?#22242;(纽交所代码:BABA)在香港联合交易所网站提交
最新文章
.NET生成水印更好的方法实例代码

.NET生成水印更好的方

这篇文章主要给大家介绍了关于.NET中生成水印更好的方
ASP.NET如何自定义项目模板详解

ASP.NET如何自定义项

这篇文章主要给大家介绍了关于ASP.NET如何自定义项目
.NET生成动态验证码的完整步骤

.NET生成动态验证码的

这篇文章主要给大家介绍了关于.NET生成动态验证码的完
ASP.NET Core MVC学习之视图组件(View Component)

ASP.NET Core MVC学习

这篇文章主要给大家介绍了关于ASP.NET Core MVC学习之
你应该知道的.NET错误与异常处理机制

你应该知道的.NET错误

这篇文章主要给大家介绍了关于.NET错误与异常处理机制
WCF中使用nettcp协议进行通讯的方法

WCF中使用nettcp协议

这篇文章主要给大家介绍了关于WCF中使用nettcp协议进
幸运蛋蛋pc开奖 真人捕鱼游戏大厅 重庆快乐十分投注平台 捕鱼达人千炮版360专区 山东时时犯罪记录 财神捕鱼打财神技巧 dnf刷团赚钱吗 赛车飞艇就是骗局 大乐透走势图新浪爱彩 球探比分网下载 重庆时时全天计划100