The micro-channel .NET applet to obtain the user UnionID


In the actual project development we often encounter the problem of unified account, how to ensure that members of the same or a single user account at different ends or different login (easy to manage user information). During this time there is such a demand, before customers make a micro letter applet Mall (owner-side), then and now want to be a member of the small end shopping malls program. First, before the user login credentials are using the unique identification micro-channel openid to do, and now the customer needs to do is end user in small membership program to jump to the end of the small shopkeeper before the program if the user is in the micro-channel end audit by the owner users do not need to review the information submitted during the operation, log in directly. So, we used to associate UnionID, as is the basic process that we now project (painting ugly mo offense).

Talk about UnionID mechanisms:

If developers have multiple mobile applications, web applications, and the public accounts (including applets), can be used to distinguish users by UnionID unique, because as long as the mobile applications in the same WeChat open platform accounts, web applications, and the public accounts (including applets), users UnionID is unique. In other words, the same user, the same for different applications in a micro-channel open platform, unionid same.

Official UnionID mechanism details: https: //

WeChat open platform bind small program flow:

Login WeChat open platform – Management Center – applet – binding applet (direct use of micro-channel official figure)

Small micro-channel acquisition program in two ways UnoinID of:

Call Interface wx.getUserInfo, get UnionID from the decrypted data (encryptedData) in (recommended):

Recommended reason: without concern for the public micro-channel number to get to UnionID.

Call Interface wx.getUserInfo premise: allows authorized users to obtain user information!

Developers background check and decryption of open data:

In order to ensure that micro-channel user information, the user interface to obtain the encrypted wx.getUserInfo related to sensitive information. Encryption symmetric encryption (will be mentioned later), we first need to login flow through micro letter applet to obtain the user’s session_key (session key), then we can make use of the acquired session key caching to save it by authorized users users get relevant information, as is successfully authorized users to obtain user information:

The basic flow chart is as follows:



(EncryptedData) data encryption and decryption algorithms:

The developer needs to obtain sensitive data, the encrypted data need (encryptedData) symmetrically decrypts the returned interface. Decryption algorithm is as follows:

    Symmetric decryption algorithm is AES-128-CBC, padding data in PKCS # 7.

    Target ciphertext decrypted symmetric Base64_Decode (encryptedData).

    Symmetrical decryption key aeskey = Base64_Decode (session_key), aeskey is 16 bytes.

    Symmetric decryption algorithm initial vector is Base64_Decode (iv), wherein the data is returned by the interface iv

I regret that the letter did not actually provide micro decryption algorithm demo for our big .Net, it is not the people, herself, according to information on the Internet or accompanied by a decryption algorithm in line with micro-channel symmetric encryption.


First, on access session_key of (session key), see the following manner wx.login + code2Session

Obtaining call interface wx.getUserInfo encryptedData (encrypted data), and IV (Initial Vector):


The user has authorized

wx.getUserInfo({ success: function(res) { console.log(res); var userInfo = res.userInfo //

Basic user information

let sessionKey = wx.getStorageSync("session_key");//临时会话密钥,通过小程序登录流程获取到的 //

Interface decryption request .net webapi

wx.request({ url: '', data: { sessionKey:sessionKey, encryptedData:res.encryptedData, iv:res.iv }, header: { 'content-type': 'application/json' //


}, success (res) { //

Decryption return over UnionID

console.log( } }) } }) })

.Net WebApi decrypt data interface:

        /// 解密微信对称加密数据,获取用户联合运营编号

Temporary session key


Micro-channel user sensitive data encrypted


Decryption initialization vector

/// [HttpGet] public IHttpActionResult DecryptSensitiveData(string sessionKey,string encryptedData,string iv) { try { var getUnionId=DecryptByAesBytes(encryptedData, sessionKey, iv); return Json(new { code =1, msg="

Decryption is successful

",result= getUnionId }); } catch (Exception ex) { return Json(new { code = 0, msg = "

Decryption failed because:

"+ex.Message }); } } #region AES对称解密 /// /// AES解密 /// ///

An array of bytes to be decrypted


Decryption key byte array


Byte array initialization vector IV


Operation mode


Fill mode

/// private static string DecryptByAesBytes(string encryptedData, string sessionKey, string iv) { try { //

Verification is not empty

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 symmetric decryption result:

" + decryptResult); return decryptData.unionid; } else { return ""; } } catch (Exception e) { JJHL.Utility.Loghelper.WriteLog("

AES symmetric decryption reasons for failure:

" + e.Message); return ""; } } #endregion

Exception encountered: Convert.FromBase64String conversion parameters, the prompts “invalid length Base-64 array of characters” problem:

The reason: When encryption parameters “+” to pass over the address bar, the background will be parsed into a space (the probability of experiencing relatively small).

Solution: The best practice is to use encryptedData.Replace ( “+”, “% 2B”) encodes a space first, and then passed as a parameter to another page, this page will only extract parameters “% 2B” decoded but here for simplicity plus the space for the direct reduction “+” is a direct replacement for or in the background space is “+” encryptedData.Replace ( ”, ‘+’).;

+ Code2Session directly to the user acquired by wx.login UnionID:

In fact, this is the way to achieve a login process applet, micro-channel official details:

Pros: without user authorization.

Premise: Users need to focus on the micro-channel public number.

End call interface applet code wx.login obtain credentials, the user interface to obtain information (UnionID, openid, session_key session key) by requesting auth.code2Session two ways:

1. wx.login directly to the code request credentials, the user acquires the address information in the request:


See detailed description of micro-channel official document (Code omitted): https: //

2. Get code credential by requesting wx.login, an interface to request code2Session rear .net webapi:

The reason: because we need to do related business logic processing of user access to information.

Applet micro-channel side code:

userLogin: function() {
var that = this;

The method defined promise

return new Promise(function(resolve, reject) { //

Interface login call

wx.login({ success: function(res) { if (res.code) { console.log("

User login authorization code is:

" + res.code); //

Call wx.request pass code request in exchange for user credentials openid, backstage and get user information

wx.request({ url: '',//

Background information requesting user Method

data: { code: res.code //

voucher code

}, header: { 'content-type':'application/json' //


}, success(res) { console.log( if ( == 0) { //

Stored in the session cache


Micro-channel user unique identification


Micro-channel platform developed jointly ID


*** NOTE **** session key // // Note: This is directly session_key cached, wx.getUserInfo will be used to in the above


promise a successful data back mechanism

{ reject(
'error'); }
}, fail: function(res)
wx.showToast({ title:

system error

' })
}, complete: ()
=> { } //

After the complete interface to perform the callback function, regardless of success or failure will be called

}) } else
}) })}

.Net WebApi requesting user interface information:

        /// 获取用户信息

Information voucher code data

/// [HttpGet] public IHttpActionResult GetUserInfo(string code) { string AppSecret = "

Applet key

"; string AppId = "

Application Identity

"; try { //

And request destination address parameters (

authorization_code授权类型,此处只需填写 authorization_code)
                string OauthUrl = "" + AppId + "&secret=" + AppSecret + "&js_code=" + code + "&grant_type=authorization_code";//

Analytical data serialized

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 = "

Failed to obtain user information

" + ex.Message }); } } /// /// 请求code2Session接口获取用户信息 /// ///

And destination address parameters

/// 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(retString); } public class WxOauthModle { /// /// 用户唯一标识 /// public string openid { get; set; } /// /// 会话秘钥 /// public string session_key { get; set; } /// /// 联立编号 /// public string unionid { get; set; } /// /// 错误码 /// public int errcode { get; set; } /// /// 错误信息 /// public string errmsg { get; set; } }

About user micro-letter web development solutions through different mechanisms UnionID public number, or between public number, account number reunification mobile applications:

For more details, please click Description: https: //

Leave a Reply