微信登錄授權, 並且解密加密內容獲取手機號和地區


所使用的的依賴

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>2.3.3.RELEASE</version>
    </dependency>
    <!--fastjson-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.72</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.59</version>
    </dependency>

</dependencies>

1.微信登錄授權, 獲取openId

    @ApiOperation(value = "用戶登錄,三個參數為code, avatarUrl, nickName")
    @PostMapping("/login")
    public ResultBean getWxCode(@RequestParam(value = "code") String code, @RequestParam(value = "wxName") String wxName,
                                @RequestParam(value = "userAvatar") String userAvatar,
                                HttpServletRequest request) {
        // 配置請求參數
        Map<String, String> param = new HashMap<>();
        param.put("appid", WxLoginCommons.WX_LOGIN_APPID);
        param.put("secret", WxLoginCommons.WX_LOGIN_SECRET);
        param.put("js_code", code);
        param.put("grant_type", WxLoginCommons.WX_LOGIN_GRANT_TYPE);
        // 發送請求
        String wxResult = HttpClientUtil.doGet(WxLoginCommons.WX_LOGIN_URL, param);
        JSONObject jsonObject = JSONObject.parseObject(wxResult);
        // 獲取參數返回的
        if (!jsonObject.containsKey("openid")) {
            System.out.println("沒有openid");
            return ResultBean.fail(ErrorCodeEnum.AuthorizationFail.getCode(), ErrorCodeEnum.AuthorizationFail.getMsg());
        }
        String session_key = jsonObject.get("session_key").toString();
        String open_id = jsonObject.get("openid").toString();

 		/** 業務代碼省略*/
        
        // 封裝返回小程序
        Map<String, String> result = new HashMap<>();
        result.put("sessionId", sessionId);
        result.put("userState", String.valueOf(2));
        result.put("openId", open_id);

        return ResultBean.success(200, "新用戶創建成功", result);
    }

HttpClientUtil.java

package com.wx.utils;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class HttpClientUtil {

    public static String doGet(String url, Map<String, String> param) {

        // 創建Httpclient對象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 創建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            // 創建http GET請求
            HttpGet httpGet = new HttpGet(uri);

            // 執行請求
            response = httpclient.execute(httpGet);
            // 判斷返回狀態是否為200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static String doGet(String url) {
        return doGet(url, null);
    }

    public static String doPost(String url, Map<String, String> param) {
        // 創建Httpclient對象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 創建Http Post請求
            HttpPost httpPost = new HttpPost(url);
            // 創建參數列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模擬表單
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 執行http請求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    public static String doPost(String url) {
        return doPost(url, null);
    }

    public static String doPostJson(String url, String json) {
        // 創建Httpclient對象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 創建Http Post請求
            HttpPost httpPost = new HttpPost(url);
            // 創建請求內容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 執行http請求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }
}

2. 解密加密內容

小程序代碼: 通過綁定的按鈕觸發, 用戶點擊獲取手機號並且同意后, 即可通過以下函數,輸出iv 和encryptedData, 通過解密函數, 得到加密內容

getPhoneNumber: function(e) { 
    console.log(e.detail.errMsg) 
    console.log("---------")
    console.log(e.detail.iv) 
    console.log(e.detail.encryptedData) 
    if (e.detail.errMsg == 'getPhoneNumber:fail user deny'){
      wx.showModal({
          title: '提示',
          showCancel: false,
          content: '未授權',
          success: function (res) { }
      })
    } else {
      wx.showModal({
          title: '提示',
          showCancel: false,
          content: '同意授權',
          success: function (res) { }
      })
    }
}

解密腳本(Java版)

public static JSONObject getUserInfo(String encryptedData, String sessionKey, String iv) {
    // 被加密的數據
    byte[] dataByte = Base64.decodeBase64(encryptedData);
    // 加密秘鑰
    byte[] keyByte = Base64.decodeBase64(sessionKey);
    // 偏移量
    byte[] ivByte = Base64.decodeBase64(iv);
    try {
        // 如果密鑰不足16位,那么就補足.  這個if 中的內容很重要
        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;
        }
        // 初始化
        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);// 初始化
        byte[] resultByte = cipher.doFinal(dataByte);
        if (null != resultByte && resultByte.length > 0) {
            String result = new String(resultByte, "UTF-8");
            return JSONObject.parseObject(result);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

注意, 我使用的是springboot, 但是我導入pom依賴后

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.59</version>
</dependency>

, new BouncyCastleProvider()一直爆紅, External Libraries也沒有對應的文件, 試了很多辦法, 最終解決的方法是 : 雖然pom導入依賴 idea中還是不識別這個jar包, 但是maven倉庫里面已經下載好了, 通過點擊idea右上角Project Structure->Libraries->添加這個jar包, 即可在External Libraries中導入.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM