美文网首页
微信小程序登陆

微信小程序登陆

作者: 墨色尘埃 | 来源:发表于2018-07-02 15:20 被阅读83次

如果未关注公众号,调用wx.login接口是获取不到unionid的,只能返回openid和session_key,这种情况下,就需要微信前端调用wx.getUserInfo接口获取到加密数据encryptedData和iv传给后台,后台解密得到unionid。


image.png

微信小程序登录(包括获取不到unionid的情况)
微信小程序官方文档 wx.getUserInfo(OBJECT)
微信小程序之用户数据解密(七)

后台接口:

 @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ResponseObj<BindInfo> getUserInfo(@RequestParam String code/*, @RequestParam String tokenid, @RequestParam
            String encryptedData, @RequestParam String iv*/) throws Exception {

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" +
                "wx6c5536682a2fbb01&secret=95895e544ca1b8da98da582e483751d3&js_code=" +
                code + "&grant_type=authorization_code";

        //微信端登录code值
        String wxCode = code;
        //请求地址 https://api.weixin.qq.com/sns/jscode2session
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> requestUrlParam = new HashMap<String, String>();
        //开发者设置中的appId
        requestUrlParam.put("appid", "wx6c5536682a2fbb01");
        //开发者设置中的appSecret
        requestUrlParam.put("secret", "95895e544ca1b8da98da582e483751d3");
        //小程序调用wx.login返回的code
        requestUrlParam.put("js_code", wxCode);
        //默认参数
        requestUrlParam.put("grant_type", "authorization_code");
        //发送post请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        JSONObject jsonObject = JSONObject.fromObject(UrlUtil.sendPost(requestUrl, requestUrlParam));
        String session_key = (String) jsonObject.get("session_key");
        //解密encryptedData
        JSONObject userInfos = getUserInfos(encryptedData, session_key, iv);
        String openid = (String) userInfos.get("openid");
        String unionId = (String) userInfos.get("unionId");
        BindInfo bindInfo = bindInfoMapper.selectUserId(openid, unionId);

    /**
     * 获取信息
     * getUserInfo前端获取加密数据encryptedData传给后台,后台解密
     */
    public JSONObject getUserInfos(String encryptedData, String sessionkey, String iv) {
        // 被加密的数据
        byte[] dataByte = Base64.decodeBase64(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decodeBase64(sessionkey);
        // 偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            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/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");
                return JSONObject.fromObject(result);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }

完整control

package com.jsptpd.weixinserver.restcontrol;

import com.jsptpd.weixinserver.dao.TokenMapper;
import com.jsptpd.weixinserver.dao.UserMapper;
import com.jsptpd.weixinserver.dao2.BindInfoMapper;
import com.jsptpd.weixinserver.model.BindInfo;
import com.jsptpd.weixinserver.model.Token;
import com.jsptpd.weixinserver.util.UrlUtil;

import net.sf.json.JSONObject;

import org.apache.commons.net.util.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.security.spec.InvalidParameterSpecException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

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;

/**
 * Created by HASEE on 2018/6/29 15:39
 */
@RestController
@RequestMapping("/weixin")
public class WeixinControl {

    @Autowired
    BindInfoMapper bindInfoMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    TokenMapper tokenMapper;

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ResponseObj<BindInfo> getUserInfo(@RequestParam String code/*, @RequestParam String tokenid, @RequestParam
            String encryptedData, @RequestParam String iv*/) throws Exception {

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" +
                "wx6c5536682a2fbb01&secret=95895e544ca1b8da98da582e483751d3&js_code=" +
                code + "&grant_type=authorization_code";

        //微信端登录code值
        String wxCode = code;
        //请求地址 https://api.weixin.qq.com/sns/jscode2session
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String, String> requestUrlParam = new HashMap<String, String>();
        //开发者设置中的appId
        requestUrlParam.put("appid", "wx6c5536682a2fbb01");
        //开发者设置中的appSecret
        requestUrlParam.put("secret", "95895e544ca1b8da98da582e483751d3");
        //小程序调用wx.login返回的code
        requestUrlParam.put("js_code", wxCode);
        //默认参数
        requestUrlParam.put("grant_type", "authorization_code");
        //发送post请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
        JSONObject jsonObject = JSONObject.fromObject(UrlUtil.sendPost(requestUrl, requestUrlParam));

//        String str = "{\"session_key\":\"wQC1GNJd1EKlpyd5RdsdhQ==\",\"openid\":\"oywxK1LR_7NvxDPWppj3fqcP9brQ\"," +
//                "\"unionId\":\"oIu0Y0u8-7YOm7ll4bnFX034jYvU\"}";
//        JSONObject jsonObject = JSONObject.fromObject(str);

        String session_key = (String) jsonObject.get("session_key");
        String openid = (String) jsonObject.get("openid");
        String unionId = (String) jsonObject.get("unionId");
        if (unionId != null && !"".equals(unionId)) {  //微信login接口返回中无unionid
            BindInfo bindInfo = bindInfoMapper.selectUserId(openid, unionId);
            if (bindInfo != null) {
                String uid = bindInfo.getUserId();
                String clientid = "wechat";
                if (uid == null || uid.equals("")) {
                    Error error = new Error();
                    error.errCode = Error.IllegalRequest;
                    error.errMessage = "";
                    return new ResponseObj<>(error);
                } else {
                    Token token = tokenMapper.selectByUserId1(uid, clientid);
                    if (token != null) {
                        token.setUserId(uid);
                        token.setClientId(clientid);
                        token.setTokenId(UUID.randomUUID().toString());
                        token.setTokenCreateDate(new Date());
                        tokenMapper.deleteByUserId1(uid, clientid);
                        tokenMapper.insert(token);
                        bindInfo.setTokenId(token.getTokenId());
                        return new ResponseObj<>(bindInfo);
                    } else {
                        Token token1 = new Token();
                        token1.setUserId(uid);
                        token1.setClientId(clientid);
                        token1.setTokenId(UUID.randomUUID().toString());
                        token1.setTokenCreateDate(new Date());

                        tokenMapper.deleteByUserId1(uid, clientid);
                        tokenMapper.insert(token1);
                        bindInfo.setTokenId(token1.getTokenId());
                        return new ResponseObj<>(bindInfo);
                    }
                }
            } else {
                Error error = new Error();
                error.errCode = Error.IllegalRequest;
                error.errMessage = "无此用户";
                return new ResponseObj<>(error);
            }
        } else {
            Error error = new Error();
            error.errCode = Error.IllegalRequest;
            error.errMessage = "请先绑定cpdat云终端";
            return new ResponseObj<>(error);
        }

//        String str = "{\"session_key\":\"wQC1GNJd1EKlpyd5RdsdhQ==\",\"openid\":\"oywxK1Ehxj9X8AElEWdS2QcZ46qs\"," +
//                "\"unionId\":\"oIu0Y0thYOJISZWzTIjTMDsqIZGo\"}";
//        JSONObject jsonObject = JSONObject.fromObject(str);
//        String session_key = (String) jsonObject.get("session_key");
//        String openid = (String) jsonObject.get("openid");
//        String unionId = (String) jsonObject.get("unionId");


//        JSONObject userInfos = getUserInfos(encryptedData, session_key, iv);
//        String openid = (String) userInfos.get("openid");
//        String unionId = (String) userInfos.get("unionId");
//        BindInfo bindInfo = bindInfoMapper.selectUserId(openid, unionId);


    }

    /**
     * 获取信息
     * getUserInfo前端获取加密数据encryptedData传给后台,后台解密
     */
    public JSONObject getUserInfos(String encryptedData, String sessionkey, String iv) {
        // 被加密的数据
        byte[] dataByte = Base64.decodeBase64(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decodeBase64(sessionkey);
        // 偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            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/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");
                return JSONObject.fromObject(result);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidParameterSpecException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }
}

相关文章

  • 如何获取小程序码

    场景一 只申请小程序码1.登陆微信小程序平台 想要生成微信的小程序码,首先要登陆到微信公众平台官网,直接在页面上输...

  • 微信小程序_01

    1.下载微信小程序编辑器:下载微信小程序编辑器 2.创建小程序应用:打开刚才下载的dmg,用微信扫面二维码登陆。点...

  • uniapp中关于APP的问题

    微信授权 1、登陆微信开放平台:https://open.weixin.qq.com/;关联应用 注意 小程序中调...

  • 小程序登录为什么能做到更好的体验

    小程序登陆为啥能做得这么简洁优雅呢?首先,我们需要大致了解小程序用户体系。 小程序用户体系 对于每个小程序,微信都...

  • 微信小程序登陆

    如果未关注公众号,调用wx.login接口是获取不到unionid的,只能返回openid和session_key...

  • 微信小程序登陆

    简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实...

  • 小程序登陆总结

    小程序登陆流程图 微信小程序登陆流程总结: wx.login的过程 首先发送wx.login得到code 发送给后...

  • Error: tunneling socket could no

    一、问题描述: 微信小程序在本地登陆不了 报错Error: tunneling socket could not ...

  • 微信小程序基础

    微信小程序介绍微信小程序开发工具的使用微信小程序框架文件微信小程序逻辑层微信小程序视图层微信小程序组件介绍微信小程...

  • 微信小程序利用openid登录

    这次是通过微信小程序的openid登陆,openid是用户的唯一标识

网友评论

      本文标题:微信小程序登陆

      本文链接:https://www.haomeiwen.com/subject/kblluftx.html