小程序登录java后端实现

小程序登录流程图如下:
小程序登录java后端实现

 

 微信开发文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

(1)前端调用 wx.login() 获取 code ,传到开发者服务器。服务端相关代码:

@GetMapping("getOpenId/{code}")
    public Wrapper<?> getOpenId(@PathVariable String code) {
        if (StringUtils.isEmpty(code)) {
            return WrapMapper.error(ErrorCodeEnum.ILLEGAL_ARGUMENT);
        }
        Map<String, String> map = appletService.getOpenId(code);
        return CollectionUtils.isEmpty(map) ? WrapMapper.error("请求失败!") : WrapMapper.ok(map);
    }
    public final static String URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code";
    @Value("${wx.appid}")
    private String appid;
    @Value("${wx.appsecret}")
    private String appsecret;

    @Override
    public Map<String, String> getOpenId(String code) {
        String requestUrl = URL.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
        CloseableHttpClient client = HttpClientBuilder.create().build();
        Map<String, String> result = new HashMap<>();
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(requestUrl);
            response = client.execute(httpGet);
            HttpEntity responseEntity = response.getEntity();
            String entry = EntityUtils.toString(responseEntity);
            log.info("响应状态为:" + response.getStatusLine());
            if (!StringUtils.isEmpty(entry)) {
                log.info("响应内容为:" + entry);
                JSONObject json = JSONObject.parseObject(entry);
                String openid = String.valueOf(json.get("openid"));
                String sessionKey = String.valueOf(json.get("session_key"));
                String unionid = String.valueOf(json.get("unionid"));
                String errcode = String.valueOf(json.get("errcode"));
                String errmsg = String.valueOf(json.get("errmsg"));
                result.put("openid", openid);
                result.put("sessionKey", sessionKey);
                result.put("unionid", unionid);
                result.put("errcode", errcode);
                result.put("errmsg", errmsg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (client != null) {
                    client.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

(2)前端通过wx.getUserInfo获取加密过的数据encryptedData和解密参数iv,传递到后端获取手机号

@PostMapping("getPhoneNumber")
    public Wrapper<?> getPhoneNumber(@RequestParam("encryptedData") String encryptedData, @RequestParam("sessionKey") String sessionKey, @RequestParam("iv") String iv) {
        if (StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(sessionKey) || StringUtils.isEmpty(iv)) {
            return WrapMapper.error(ErrorCodeEnum.ILLEGAL_ARGUMENT);
        }
        String phoneNumber = appletService.getPhoneNumber(encryptedData, sessionKey, iv);
        return WrapMapper.ok(phoneNumber);
    }
@Override
    public String getPhoneNumber(String encryptedData, String sessionKey, String iv) {
        byte[] dataByte = Base64.decode(encryptedData);
        byte[] keyByte = Base64.decode(sessionKey);
        byte[] ivByte = Base64.decode(iv);
        try {
            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/PKCS5Padding");
            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, StandardCharsets.UTF_8);
                log.info("获取手机号信息:{}", JSONObject.parseObject(result));
                return (String) JSONObject.parseObject(result).get("phoneNumber");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

(3)将手机号和应用app做关联,获取到app中对应的用户信息。

小程序登录java后端实现

上一篇:braise脚本学习实践--删除微信和QQ本地缓存文件


下一篇:使用Promise封装小程序wx.request的实现方法