首先我要怒骂微信的后台开发 真的还是乱七八糟。

首先我们登录微信开发平台

选择要开发的类型

然后小程序登录:选择

微信小程序实现微信登录详解(JAVA后台)官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

附官方文档地址:小程序登陆 | 微信开放文档
编码前准备工作:开发之前我们需要准备两个东西AppID和AppSecret,需要到微信开放平台(https://open.weixin.qq.com)注册开发者账号,并在移动应用中将我们的APP创建进去,填写对应资料后提交审核
准备工作做好后我们开始实现,我们项目用的是springBoot+mybatis框架进行的接口开发
1.第一步是由app端调起微信授权登录页面让用户进行授权操作,用户确认授权后会返回一个code,这个code就是我们后面获取授权用户信息的关键
2.拿着第一步获得的code去获取用户信息并进行登录操作

package com.macro.mall.controller;
import cn.hutool.core.codec.Base64;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Controller
@Api(tags = "WxSmallProgramController")
@Tag(name = "WxSmallProgramController", description = "小程序微信登录")
@RequestMapping("/wxs")
public class WxSmallProgramController {
    private String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
    private String appId ="";
    private String secret ="";
    public JSONObject getSessionKeyOrOpenId(String code)  {
        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;
    }
    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;
    }
    public static JSONObject getUserInfo(String encryptedData, String iv, String sessionKey) {
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(iv);
        try {
            // 如果密钥不足16位,那么就补足.
            int base = 16;
            keyByte = completToBase(keyByte, base);
            ivByte = completToBase(ivByte, base);
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = null;
            try {
                cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
            } catch (NoSuchProviderException e) {
                e.printStackTrace();
            }
            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) {
            e.getMessage();
        } catch (NoSuchPaddingException e) {
            e.getMessage();
        } catch (InvalidParameterSpecException e) {
            e.getMessage();
        } catch (IllegalBlockSizeException e) {
            e.getMessage();
        } catch (BadPaddingException e) {
            e.getMessage();
        } catch (UnsupportedEncodingException e) {
            e.getMessage();
        } catch (InvalidKeyException e) {
            e.getMessage();
        } catch (InvalidAlgorithmParameterException e) {
            e.getMessage();
        }
        return null;
    }
    //补全数组位数
    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;
        }
    }
} 
 
前端我们可以微信开发者工具去调用 有的时候 报下面错误 大家处理一下
HbuilderX运行小程序报错解决:[error] IDE service port disabled. To use CLI Call, please enter y to confirm
提示:IDE service port disabled. To use CLI Call, open IDE -> Settings -> Security Settings, and set Service Port On。
意思是:IDE服务端口禁用。要使用CLI调用,请打开IDE ->设置->安全设置,并设置服务端口On。解决如下:
打开微信开发者工具,
点击齿轮“设置”,
选择“安全”,
然后在“服务端口”选项-点击“开启”。
-end




















