Java SpringBoot 实现微信小程序登录,获取用户信息、手机号、用户公众号openId

  • Post author:
  • Post category:java


微信小程序登录文档:

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html


先做好前期准备工作哈



1. POM文件

下列 maven 坐标有已经存在则忽略

		<!-- utils -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.60</version>
		</dependency>
		
		<!--commons -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.6</version>
		</dependency>
		<dependency>
			<groupId>commons-configuration</groupId>
			<artifactId>commons-configuration</artifactId>
			<version>1.10</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
		</dependency>
		
		<dependency>
			<groupId>com.fasterxml</groupId>
			<artifactId>classmate</artifactId>
			<version>1.4.0</version>
		</dependency>
		
		<!--解析Emoji表情 -->
		<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.0</version>
        </dependency>



2. 创建解密工具AES

import org.bouncycastle.jce.provider.BouncyCastleProvider;
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.security.*;


public class AES {
public static boolean initialized = false;

    /**
     * AES解密
     * @param content 密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
//            Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");

            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public static void initialize(){
        if (initialized) return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    //生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception{
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}



3. 核心代码

 	/**
     * 获取微信小程序 用户信息或用户手机号码
     * @param code 调用微信登陆返回的Code
     * @return
     */
    @RequestMapping("/getSessionKeyOropenid")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public synchronized JSONObject getSessionKeyOropenid(String code, String iv, String encryptedData) throws Exception {
        System.out.println("code:" + code);
        System.out.println("iv:" + iv);
        System.out.println("encryptedData:" + encryptedData);

        CloseableHttpClient httpclient = HttpClients.createDefault();
        //发送get请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        HttpGet httpget = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code");
        CloseableHttpResponse response = httpclient.execute(httpget);

        HttpEntity entity = response.getEntity();
        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(entity));
        logger.info(jsonObject.toJSONString());

//----------------------------------解密用户信息-----------------------------------------
        String userInfo = null;
        JSONObject userInfoJSON = null;
        Thread.sleep(500);
        try {
            byte[] resultByte = AES.decrypt(Base64.decodeBase64(encryptedData),
                    Base64.decodeBase64(jsonObject.getString("session_key")),
                    Base64.decodeBase64(iv));

            userInfo = new String(resultByte, "UTF-8");
            System.out.println("userInfo:" + userInfo);
            userInfoJSON = JSON.parseObject(userInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("userInfo:" + userInfoJSON);
//----------------------------------解密用户信息-----------------------------------------

		//具体可以获取什么用户信息可以到微信小程序文档查看
		//注意:获取用户信息和获取用户手机号 这两个是单独获取的,不能同时获取
        System.out.println("openId:" + jsonObject.getString("openid"));
        System.out.println(EmojiUtil.toHtmlHex(userInfoJSON.getString("nickName")));
        
        return userInfoJSON;
    }


	/**
     * 获取微信公众号用户openid
     * @param code 调用微信登陆回调返回的Code,state
     * @return
     */
    @RequestMapping("/weChatMp")
    @Transactional(rollbackFor = Exception.class)
    public synchronized String weChatMp(String code, String state) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        //发送get请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session
        HttpGet httpget = new HttpGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appIdMp + "&secret=" + appSecretMp + "&code=" + code + "&grant_type=authorization_code");
        CloseableHttpResponse response = httpclient.execute(httpget);

        HttpEntity entity = response.getEntity();
        JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(entity));
        System.out.println("--------------获取微信公众号用户openid返回的数据:---------------");

        System.out.println("MemberInfo:" + jsonObject.toJSONString());
        System.out.println("state:" + state);	//这里的 state 是前端传过来的自定义内容参数
        System.out.println("openid:" + jsonObject.getString("openid"));

        System.out.println("--------------获取微信公众号用户openid返回的数据:---------------");


        return "redirect:https://hkhxjx.wegouer.com/a.html";	//在微信小程序获取完微信公众号openId之后重定向页面
    }



注意:


  • 微信小程序登录 后端 获取手机号的流程 与 获取用户信息流程相同。前端传过来的参数不同

  • 微信小程序 获取 用户微信公众号openId 前提 是用户要关注此公众号



版权声明:本文为weixin_43910274原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。