Java实现微信小程序授权手机号登陆(史上最简单)

基本流程就是

1、前端向微信获取code给个后端,后端根据code换取openid和sessionKey

2、前端用户点击授权调用微信getPhoneNumber方法获取加密的用户数据,即加密encryptedData和iv,传给后端

3后端解密encryptedData和iv拿到用户手机号执行登陆注册的逻辑

在这里插入图片描述

注:getPhoneNumber方法必须绑定在button组件里。详情官网:微信小程序获取手机号

本人为后端攻城狮所以只能提供后端逻辑,废话少说直接上代码

1、后端拿到code、encryptedData、iv开始一顿操作...

public String wxRegistry(String encryptedData, String iv, String code) {

        //第一步:通过code获取openid sessionKey
        JSONObject sessionKeyOrOpenId = getSessionKeyOrOpenId(code);

        String openid = sessionKeyOrOpenId.getStr("openid");
        String sessionKey = sessionKeyOrOpenId.getStr("session_key");

        //第二步:从encryptedData iv 解密 用户信息 拿到手机号
        JSONObject userInfo = getUserInfo(encryptedData, iv, sessionKey);

        String phone = userInfo.getStr("phoneNumber");

        System.err.println("--------------------------------------------");
        System.err.println("执行手机号注册登录逻辑");
        System.err.println("--------------------------------------------");

         return null;
        }

2、提供code换openid和sessionKey的方法

    @Value("${wechat.sessionHost}")
    private String requestUrl;

    @Value("${wechat.appId}")
    private String appId;

    @Value("${wechat.secret}")
    private String secret;

    public JSONObject getSessionKeyOrOpenId(String code) throws CustomizeException {

        Map<String, Object> requestUrlParam = new HashMap<>();
        requestUrlParam.put("appid", appId);//小程序appId
        requestUrlParam.put("secret", secret);//小程序 appSecret
        requestUrlParam.put("js_code", code);//小程序端返回的code
        requestUrlParam.put("grant_type", "authorization_code");//默认参数

        //发送post请求读取调用微信接口获取openid用户唯一标识
        //我用的hutool工具包的HttpUtil、JSONUtil,各位按需导入
        JSONObject SessionKeyOpenId = null;
        try {
            String result = HttpUtil.get(requestUrl, requestUrlParam);
            SessionKeyOpenId = JSONUtil.parseObj(result);
        } catch (Exception e) {
              e.printStackTrace();
        }
        return SessionKeyOpenId;
    }

3、解密encryptedData和iv拿到用户信息的方法 


    public static JSONObject getUserInfo(String encryptedData, String iv, String sessionKey) {
        // 被加密的数据
        byte[] dataByte = cn.hutool.core.codec.Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = cn.hutool.core.codec.Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = cn.hutool.core.codec.Base64.decode(iv);
        try {
            // 如果密钥不足16位,那么就补足.
            int base = 16;
            keyByte = completToBase(keyByte, base);
            ivByte = completToBase(ivByte, base);

            // 初始化
            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");
                System.out.println(result);
                return JSONUtil.parseObj(result);
            }
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
        } catch (NoSuchPaddingException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidParameterSpecException e) {
            log.error(e.getMessage(), e);
        } catch (IllegalBlockSizeException e) {
            log.error(e.getMessage(), e);
        } catch (BadPaddingException e) {
            log.error(e.getMessage(), e);
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidKeyException e) {
            log.error(e.getMessage(), e);
        } catch (InvalidAlgorithmParameterException e) {
            log.error(e.getMessage(), e);
        } catch (NoSuchProviderException e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

 4、解密需要用到一个补全位数的工具方法

 //补全数组位数
    public static byte[] completToBase(byte[] bytes, int base) {
        byte[] temp = new byte[]{};
        if (bytes.length % base != 0) {
            int groups = bytes.length / base + (bytes.length % base != 0 ? 1 : 0);
            temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(bytes, 0, temp, 0, bytes.length);
            return temp;
        } else {
            return bytes;
        }
    }

 5、配置文件

至此授权手机号登录完成!so easy。

猜你喜欢

转载自blog.csdn.net/weixin_52540274/article/details/120435979