My hobby is to make plans, overturn plans, make plans again, and let others supervise my study, supervise my weight loss, and supervise me to change my bad habits. So I'm going to make a little program for myself. The layout of the applet interface is almost finished. Now let's register and log in your application.
1, Applet side:
1,.wxml
<view class="container"> <button class="to-login" open-type="getUserInfo" bindtap="getUserInfo">Land</button> </view>
2. . js: call the interface wx.login to get the code, wx.getUserInfo to get the encryptedData and iv, and pass the code, encryptedData and iv to the background
getUserInfo: function () { //Open the loading box wx.showLoading({ title: 'Logging in...', mask: true }); // Sign in wx.login({ success: function (res_login) { if (res_login.code) { //Get user information wx.getUserInfo({ lang:'zh_CN', success: res => { console.log(res) wx.request({ url: 'http://192.168.1.101:8080/login/wx_login', data: { code: res_login.code, encryptedData: res.encryptedData, iv: res.iv }, header: { 'content-type': 'application/json' }, success: res => { //1. Save user information to local storage wx.setStorageSync('userInfo', res.data) //2. Save user information to global variables var app = getApp(); app.globalData.userInfo = res.data //Hide loading box wx.hideLoading(); }, fail: res => { wx.showToast({ title: 'Login failed', icon: 'none' }) } }) } }) } } }); },
2, Use Spring boot for backend
1. Get openid according to code
The backend receives the code from the applet, and sends it to the wechat server together with appid and secret to obtain the openid and session Φ u key. Openid is mainly used to register and log in, and the openid existence database is the unique identification of user existence. Session [u key is used as the state to judge whether to log off or not, and the returned business data will take this state (do not return session [u key directly here, you can generate a unique string for each session as a key, and then you can use session [u key and openid as values).
/** * Wechat applet login registration (if there is a value through openID, the login information will be returned directly, otherwise the user information will be inserted into the database) * @param code code Parameter to get the user's openId * @param encryptedData Encrypted data of complete user information including sensitive data * @param iv Initial vector of encryption algorithm * @return */ @GetMapping("/wx_login") public ResponseBO<WxResponseVO> wxLogin(@RequestParam(required = false) String code,String encryptedData, String iv) { // Get openID and session ﹐ key String SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APPID + "&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code"; RestTemplate sessionRestTemplate = new RestTemplate(); ResponseEntity<String> sessionResponseEntity = sessionRestTemplate.exchange(SESSION_URL, HttpMethod.GET, null, String.class); if (sessionResponseEntity != null && sessionResponseEntity.getStatusCode() == HttpStatus.OK) { //Analyze the openid and session_key obtained from wechat server; String sesionData = sessionResponseEntity.getBody(); Gson gson = new Gson(); WxResponseVO weChatSession = gson.fromJson(sesionData, WxResponseVO.class); //Get session key String session_key = weChatSession.getSession_key(); // Cache session [key RedisUtils.set("session_key", session_key, weChatSession.getExpires_in()); //Get the unique identity of the user String openid = weChatSession.getOpenid(); // Query the database according to openID. If there is a value, the login information will be returned directly. If there is no value, the user information will be inserted into the database String userInfo = getUserInfo(encryptedData,session_key,iv); } return null; }
2. According to session_key, encryptedData and iv, wechat user information can be decrypted.
/** * Decrypt user sensitive data to obtain user information * @param sessionkey Key to encrypt and sign data * @param encryptedData Encrypted data of complete user information including sensitive data * @param iv Initial vector of encryption algorithm */ public String getUserInfo(String sessionkey, String encryptedData, String iv){ // Encrypted data byte[] dataByte = Base64.decode(encryptedData); // Encryption key byte[] keyByte = Base64.decode(sessionkey); // Offset byte[] ivByte = Base64.decode(iv); try { // If the key is less than 16 bits, it will be supplemented. The content in this if is very important int base = 16; if (keyByte.length % base != 0) { int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0); byte[] temp = new byte[groups * base]; Arrays.fill(temp, (byte) 0); System.arraycopy(keyByte, 0, temp, 0, keyByte.length); keyByte = temp; } // initialization Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC"); SecretKeySpec spec = new SecretKeySpec(keyByte, "AES"); AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES"); parameters.init(new IvParameterSpec(ivByte)); cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// initialization byte[] resultByte = cipher.doFinal(dataByte); if (null != resultByte && resultByte.length > 0) { String result = new String(resultByte, "UTF-8"); return result; } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidParameterSpecException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { e.printStackTrace(); } return null; }
3, After logging in, it returns the session [u key] to the applet. The applet uses Wx. Setstoragesync ('session [u key], res.data. Data. Session [u key) to cache. Later, the returned business data will take this status.