zoukankan      html  css  js  c++  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中对应的用户信息。

  • 相关阅读:
    call_user_func和call_user_func_array的区别
    25行实现文件上传功能(PHP)
    PHP 结合MYSQL简单的实现了Todo List 功能
    向ASP.NET自定义控件中嵌入CSS资源
    模态子窗口不执行page_load
    oracle一次插入多条数据
    转载:数据库表结构设计方法及原则
    Js中的window.parent ,window.top,window.self
    在一个JS文件中包含中文字符串通过innerHTML输出后中文乱码
    转载:数据库表结构设计方法及原则
  • 原文地址:https://www.cnblogs.com/wlong-blog/p/14754138.html
Copyright © 2011-2022 走看看