gogoWebsite

WeChat small program and WeChat public number the same user login problem

Updated to 6 months ago

WeChat small program and WeChat public number the same user login problem


Recently, I've been working on the interface to merge the WeChat small program with the WeChat public number login. Organize relevant information and personal knowledge of the experience wrote this article to share with you.


First of all, briefly I encountered the problem is that our program call WeChat small program to get openid, and then through the openID to get the user's unique identity, the user can log in, however, when we call WeChat public also the same to the openid, the same to the user two different openid, can not distinguish whether it is the same user, and then found that no matter call WeChat small program or WeChat public number of the same user to the unionid is the same, so we will use the unionid to distinguish whether the same user.


UnionID mechanism description:

If a developer has multiple mobile apps, web apps, and public accounts (including small programs), the uniqueness of the user can be distinguished by the unionid, because as long as the mobile apps, web apps, and public accounts (including small programs) are under the same WeChat Open Platform account, the user's unionid is unique. In other words, the same user, for different applications under the same WeChat Open Platform, the unionid is the same.


1, for the small program to get unionid:


Let's look at the timing diagram when a user logs into the applet:



1. (JAVA backend) make a request to WeChat server with js_code, appId, secretkey and grant_type parameters in exchange for the user's openid and session_key (session key)


Exchange session_key, openid with code (obtained by calling WeChat interface on the front-end)


This is an HTTPS interface where the developer server uses the login credentials code to get the session_key and openid.
where session_key is the key for cryptographically signing user data. For your own application security, session_key should not be transmitted over the network. It is used for decryption in the background.


Interface Address:


/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

Request parameter description:


1 Parameter Required or Not Required Description
2 appid is a unique identifier of the app, which is obtained after the submission of the app to WeChat Open Platform is approved.
3 secret is the application key AppSecret, which is obtained after submitting the application to WeChat Open Platform for review and approval.
4 js_code is Fill in the code parameter obtained in the first step.
5 grant_type is the authorization_code.

Map<String, String> params = new HashMap<String, String>();
("appid", APPID);
("secret", SECRET);
("js_code", "js_Code");
("grant_type", "authorization_code");
String openidtoken = (/sns/jscode2session, proxy, params,
utf-8, 60000);


Returns the parameters:

parameters clarification
openid user-unique identifier
session_key session key


2, AES decryption core code: (encryptedData information containing sensitive user information is provided by the front-end, and the back-end is responsible for decrypting the data and getting the unionId)

		public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
			initialize();
			try {
				Cipher cipher = ("AES/CBC/PKCS7Padding");
				Key sKeySpec = new SecretKeySpec(keyByte, "AES");

				(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// initialization
				byte[] result = (content);
				return result;
			} catch (NoSuchAlgorithmException e) {
				();
			} catch (NoSuchPaddingException e) {
				();
			} catch (InvalidKeyException e) {
				();
			} catch (IllegalBlockSizeException e) {
				();
			} catch (BadPaddingException e) {
				();
			} catch (NoSuchProviderException e) {
				// TODO Auto-generated catch block
				();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				();
			}

3. Decrypt user information:

		byte[] resultByte = (
								Base64.decodeBase64(encryptedData),
								Base64.decodeBase64(session_key),
								Base64.decodeBase64(ivByte));

		if (null != resultByte && > 0) {
			String userInfo = new String(resultByte, "UTF-8");
			// fate fatejson
			JsonObject jsonobject = null;
			try {
				JsonParser par = new JsonParser();
				JsonElement jsonelement = (userInfo);
				jsonobject = ();
			} catch (Exception e) {
				。。。。。。
			}
			// gainunionid
			unionID = ("unionId").getAsString() + "";
		}


Note: Conversion between String and byte arrays:


The byte array can be obtained by Base64.decodeBase64(String).


By String userInfo = new String(resultByte, "UTF-8"); then you get the desired String


4. The result obtained by decryption:
The encryption process is done on WeChat server and the decryption process is done on our server, i.e. we get the following data from encryptData.
{
"openId": "OPENID",
"nickName": "NICKNAME",
"gender": GENDER,
"city": "CITY",
"province": "PROVINCE",
"country": "COUNTRY",
"avatarUrl": "AVATARURL",
"unionId": "UNIONID",
"watermark":
{
"appid":"APPID",
"timestamp":TIMESTAMP
}
}
5, to get the unionId and the user's unique identity bound together, through the identification of the next step can be operated, the system is different, the operation is different, here no longer in detail.




2. For the public to get unionId:


1, first take the code to get the web authorization access_token and openid


Interface Address:


/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=JSCODE&grant_type=authorization_code

Request parameter description:


1 Parameter Required or Not Required Description
2 appid is a unique identifier of the app, which is obtained after the submission of the app to WeChat Open Platform is approved.
3 secret is the application key AppSecret, which is obtained after submitting the application to WeChat Open Platform for review and approval.
4 code Yes Fill in the code parameter obtained in the first step
5 grant_type is the authorization_code.

Map<String, String> params = new HashMap<String, String>();
("appid", APPID);
("secret", SECRET);
("code", "Code");
("grant_type", "authorization_code");
String openidtoken = (/sns/oauth2/access_token, proxy, params,
utf-8, 60000);


Returns the parameters:

"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE" 
}
Parameter Description
access_token interface call credentials
expires_in access_token interface call credential timeout in (seconds)
refresh_token User refresh access_token
openid Unique identifier for authorized users
scope User-authorized scope, separated by commas (,).


2, you can see that in addition to access_token, you can also get openid, with the access_token and openid to get unionID


Interface Address:


/sns/userinfo?appid=APPID&secret=SECRET&code=JSCODE&grant_type=authorization_code

Request parameter description:


1 Parameter Required or not Description
2 access_token be interface invocation credential
3 openid         Yes Unique identification of authorized users
4 lang           No Generally fixed value zh_CN

Map<String, String> params = new HashMap<String, String>();
("access_token", access_token);
("openid", openId);
("lang", "zh_CN");
String openidtoken = (/sns/userinfo, proxy, params,
utf-8, 60000);


The user's unionID is included in the return value, so we won't go into details here.



Work a little harder every day and get better every day.