欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net之微信小程序獲取用戶UnionID的實現

 更新時間:2019年09月01日 10:59:25   作者:追逐時光  
這篇文章主要介紹了.Net之微信小程序獲取用戶UnionID的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言:

在實際項目開發(fā)中我們經常會遇到賬號統一的問題,如何在不同端或者是不同的登錄方式下保證同一個會員或者用戶賬號唯一(便于用戶信息的管理)。這段時間就有一個這樣的需求,之前有個客戶做了一個微信小程序商城(店主端的),然后現在又要做一個會員購物端的小程序商場。首先之前用戶登錄憑證都是使用微信openid來做的唯一標識,而現在客戶需求是要做到用戶在會員端小程序跳轉到到店主端小程序假如之前該用戶微信是在店主端審核通過的用戶則不需要在進行資料提交審核操作,直接登錄。所以,所以我們使用了UnionID來進行關聯,如下是我們現在項目的基本流程(畫的丑莫見怪)。

說說UnionID機制:

如果開發(fā)者擁有多個移動應用、網站應用、和公眾帳號(包括小程序),可通過 UnionID 來區(qū)分用戶的唯一性,因為只要是同一個微信開放平臺帳號下的移動應用、網站應用和公眾帳號(包括小程序),用戶的 UnionID 是唯一的。換句話說,同一用戶,對同一個微信開放平臺下的不同應用,unionid是相同的。

官方UnionID機制詳細說明:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html

微信開放平臺綁定小程序流程:

登錄微信開放平臺— 管理中心 — 小程序 — 綁定小程序(直接使用微信官方圖)

微信小程序獲取UnoinID的兩種方式

調用接口wx.getUserInfo,從解密數據(encryptedData)中獲取 UnionID(推薦使用):

推薦使用原因:無需關注微信公眾號即可獲取到UnionID。

調用接口wx.getUserInfo前提:用戶允許授權獲取用戶信息!

開發(fā)者后臺校驗與解密開放數據:

微信為了保證用戶信息,把用戶通過wx.getUserInfo接口獲取到的相關敏感信息進行了加密。加密方式對稱加密(后面會提到),首先我們需要通過微信小程序登錄流程獲取到用戶的session_key(會話密鑰),然后我們可以報獲取到的會話密鑰使用緩存存起來,在通過用戶授權獲取用戶相關信息,如下是用戶授權成功獲取到的用戶信息:

基本流程圖如下:

(encryptedData)加密數據解密算法:

開發(fā)者如需要獲取敏感數據,需要對接口返回的加密數據(encryptedData)進行對稱解密。 解密算法如下:

  1. 對稱解密使用的算法為 AES-128-CBC,數據采用PKCS#7填充。
  2. 對稱解密的目標密文為 Base64_Decode(encryptedData)。
  3. 對稱解密秘鑰 aeskey = Base64_Decode(session_key), aeskey 是16字節(jié)。
  4. 對稱解密算法初始向量 為Base64_Decode(iv),其中iv由數據接口返回

很遺憾的是微信居然沒有為我們大.Net提供解密算法demo,實屬讓人不算,最后自己根據網上的資料還是配上了符合微信對稱加密的解密算法。

代碼實現:

首先關于session_key(會話密鑰)的獲取,請看下面的wx.login+code2Session 方式

調用接口wx.getUserInfo獲取encryptedData(加密數據)和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' // 默認值
},
success (res) {
//解密返回過來的UnionID
console.log(res.data)
}
})
}
})
})

.Net WebApi 解密數據接口:

/// <summary>
  /// 解密微信對稱加密數據,獲取用戶聯合運營編號
  /// </summary>
  /// <param name="sessionKey">臨時會話秘鑰</param>
  /// <param name="encryptedData">微信用戶敏感加密數據</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對稱解密
  /// <summary>
  /// AES解密
  /// </summary>
  /// <param name="encryptedData">待解密的字節(jié)數組</param>
  /// <param name="sessionKey">解密密鑰字節(jié)數組</param>
  /// <param name="iv">IV初始化向量字節(jié)數組</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對稱解密結果為:" + decryptResult);
     return decryptData.unionid;
    }
    else
    {
     return "";
    }
   }
   catch (Exception e)
   {
    JJHL.Utility.Loghelper.WriteLog("AES對稱解密失敗原因:" + e.Message);
    return "";
   }
  }

  #endregion

所遇異常:參數使用Convert.FromBase64String轉化時,提示“Base-64字符數組的無效長度” 的問題:

原因:加密參數中的"+"通過地址欄傳過來時,后臺會解析為空格(遇到的概率比較?。?。

解決:最好的做法是 使用encryptedData.Replace("+", "%2B")先將空格編碼,然后再作為參數傳給另一頁面?zhèn)鬟f,這樣頁面在提取參數時才會將“%2B”解碼為加號.但這兒為了簡化,將空格直接還原為"+"或者是直接在后臺將空格替換為“+”encryptedData.Replace(' ', '+');

直接通過wx.login+code2Session獲取到該用戶 UnionID:

其實這個方式就是實現了小程序的登錄流程,微信官方詳細說明:

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

優(yōu)點:無需用戶授權。

前提:用戶需要關注該微信公眾號。

小程序端調用接口wx.login獲取code憑證,在通過請求auth.code2Session接口獲取用戶信息(UnionID,openid,session_key會話密鑰)兩種方式:

1.直接通過wx.login請求到code憑證后,在請求該地址獲取用戶信息:

GET:https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

詳細說明請看微信官方文檔(代碼略):https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

2.通過請求wx.login獲取code憑證,在向.net webapi后端請求code2Session接口:

原因:因為我們需要對獲取的用戶信息做相關業(yè)務邏輯處理。

微信小程序端代碼:

復制代碼 代碼如下:
/***封裝用戶promise登錄,通過code憑證獲取用戶信息(UnionID,openid,session_key會話密鑰)*/userLogin: function() {var that = this;//定義promise方法return new Promise(function(resolve, reject) {//調用登錄接口wx.login({success: function(res) {if (res.code) {console.log("用戶登錄授權code為:" + res.code);//調用wx.request請求傳遞code憑證換取用戶openid,并獲取后臺用戶信息wx.request({url: 'https://www.xxxx.xxx.api/User_oAuth/GetUserInfo',//后臺請求用戶信息方法data: {code: res.code //code憑證},header: {'content-type':'application/json' // 默認值},success(res) {console.log(res.data)if (res.data.errcode == 0) {//存入session緩存中console.log(res.data.openid);//微信用戶唯一標識console.log(res.data.UnionID);//微信開發(fā)平臺聯合IDconsole.log(res.data.session_key);//會話密鑰 //***注意**** //注意:這里是直接把session_key緩存起來,在上面wx.getUserInfo會使用到 wx.setStorageSync("session_key",res.data.session_key);
[code]//promise機制放回成功數據 resolve(res.data); } else { reject('error'); } }, fail: function(res) { reject(res); wx.showToast({ title: '系統錯誤' }) }, complete: () => { } //complete接口執(zhí)行后的回調函數,無論成功失敗都會調用 }) } 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; }
  }

關于微信網頁開發(fā)通過UnionID機制解決用戶在不同公眾號,或在公眾號、移動應用之間帳號統一問題:

詳情說明請點擊:http://www.dbjr.com.cn/article/168982.htm

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

最新評論