zoukankan      html  css  js  c++  java
  • 微信登录授权, 并且解密加密内容获取手机号和地区

    所使用的的依赖

    <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中导入.

  • 相关阅读:
    Java 8 CompletableFuture思考
    Math.ceil 笔记
    Python virtual env
    Reactive Stream: 如何将两个数据流接到一起,然后进行操作
    基于Apollo实现.NET Core微服务统一配置(测试环境-单机)
    在ASP.NET Core 2.x中获取客户端IP地址
    Entity Framework Core(3)-配置DbContext
    .NET Core2.1下采用EFCore比较原生IOC、AspectCore、AutoFac之间的性能
    Entity Framework Core 入门(2)
    Entity Framework Core介绍(1)
  • 原文地址:https://www.cnblogs.com/wfszmg/p/14405577.html
Copyright © 2011-2022 走看看