zoukankan      html  css  js  c++  java
  • 微信小程序-getUserProfile示例与后台(已纠正)

    前段时间,微信更改了授权方式,采用用户主动式授权,也就是可授权多次,并不像之前的取消就不弹了

    下面代码效果:检测是否授权,未授权时出现授权按钮,已授权则直接显示用户信息,方式使用了缓存,有更好的方案请在评论区回复一下,(文中appid,appsecret均为测试小程序)

    index.js

    Page({
      data: {
        hasUserInfo: false,
        canIUseGetUserProfile: false,
      },
    
      onLoad() {
        /* 从缓存中取出去数据 */
        let userInfo = wx.getStorageSync('userInfo');
        let wxInfos = wx.getStorageSync('wxInfos');
        if (0 == Object.keys(userInfo).length) {
          this.setData({canIUseGetUserProfile: true})
          wx.login({success:(rs) => {wx.setStorageSync("code",rs.code); } });
        }else{
          this.setData({
            hasUserInfo:true,
            userInfo:userInfo,
            wxInfos:wxInfos
          })
        }
      },
    
      getUserProfile(e) {
        wx.getUserProfile({
          desc: '授权', 
          success: (wrs) => {
           var code = wx.getStorageSync("code")
            if(code){
              let dataJson = {
                appId: app.globalData.appId,
                code : code,
                iv : wrs.iv,
                encryptedData : wrs.encryptedData
              }
              /* 发起用户微信开放信息请求 */
              request.requestPost(true, app, '/xxx', dataJson, data =>{
                if(data.stateCode=="0"){
                  var result = JSON.parse(data.result);
                  _self.setData({
                    hasUserInfo: true,
                    userInfo:result,
                    wxInfos:JSON.parse(result.wxInfos)
                  })
                  /* 使用缓存记录信息 */
                  wx.setStorageSync('userInfo', result);
                  wx.setStorageSync('wxInfos', JSON.parse(result.wxInfos));
                }else {
                  console.log(data)
                }
              });
            }
          },fail:()=>{
            console.log("用户拒绝授权");
          }
        });
      }
    })

    index.wxml

    <view class="container">
      <view class="userinfo">
        <block wx:if="{{!hasUserInfo}}">
          <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
        </block>
        <block wx:else>
          <image bindtap="bindViewTap" class="userinfo-avatar" src="{{wxInfos.avatarUrl}}" mode="cover"></image>
          <text class="userinfo-nickname">{{wxInfos.nickName}}</text>
          <text class="userinfo-nickname">openId=> {{userInfo.openid}}</text>
          <text class="userinfo-nickname">unionId=> {{userInfo.unionid}}</text>
        </block>
      </view>
    </view>

    后台:

    GetWxInfoServlet.java

    import org.apache.commons.lang.StringUtils;
    
    import com.alibaba.fastjson.JSONObject;
    import com.src.minback.utils.HttpRequest;
    import com.src.minback.utils.WxAesUtil;
    
    /**
     * 模拟获取微信用户信息及微信小程序版本信息
     * 
     * @author liuwl
     */
    public class GetWxInfoServlet extends HttpServlet {
    
        private static final long serialVersionUID = 1L;
    
        static String wxspAppid = "wxfc5a797bc1295c71";
        static String wxspSecret = "47067172d687958df709f9396b83e3ed";
        static String grant_type = "authorization_code";
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            
            // 设置字符集
            req.setCharacterEncoding("UTF-8");
            resp.setCharacterEncoding("UTF-8");
    
            // 获取输出
            PrintWriter out = resp.getWriter();
            JSONObject jsonObj = new JSONObject();
            JSONObject result = new JSONObject();
            System.out.println("wx.login 返回的code:" + req.getParameter("code"));
            String code = req.getParameter("code");
            // 登录凭证不能为空
            if (code != null && code.length() > 0) {
                // 请求参数
                String params = "appid=" + wxspAppid + "&secret=" + wxspSecret + "&js_code=" + code + "&grant_type=" + grant_type;
                // 发送请求
                String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
                // 解析相应内容(转换成json对象)
                JSONObject json = JSONObject.parseObject(sr);
                // 获取会话密钥(session_key)
                String session_key = json.get("session_key").toString();
                System.out.println("session_key:" + session_key);
                // 用户的唯一标识(openid)
                String openid = (String) json.get("openid");
                System.out.println("openid:" + openid);
                result.put("openid", openid);
                // 开放平台的唯一标识符(unionid)
                String unionid = (String) json.get("unionid");
                System.out.println("unionid:" + unionid);
                result.put("unionid", unionid);
                if (StringUtils.isNotEmpty(openid)) {
                    jsonObj.put("stateCode", "0");
                    jsonObj.put("stateDesc", "操作成功");
                    // 解密encryptedData
                    try {
                        String encryptedData = req.getParameter("encryptedData");
                        String iv = req.getParameter("iv");
                        System.out.println("iv:" + iv);
                        System.out.println("encryptedData:" + encryptedData);
                        JSONObject decryptData = WxAesUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
                        System.out.println("-->" + decryptData);
                        if (decryptData!=null) {
                            result.put("wxInfos", decryptData.toString());
                        }
                        jsonObj.put("result", result.toJSONString());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    jsonObj.put("stateCode", "1");
                    jsonObj.put("stateDesc", "获取失败");
                }
            } else {
                jsonObj.put("stateCode", "3");
                jsonObj.put("stateDesc", "code为空");
            }
    
            System.out.println("仅获取微信用户所有信息(userData):" + jsonObj);
    
            out.print(jsonObj);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }

    工具类:WxAesUtil.java

    import org.apache.commons.codec.binary.Base64;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    import com.alibaba.fastjson.JSONObject;
    
    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;
    
    public class WxAesUtil {
        static {
            //BouncyCastle是一个开源的加解密解决方案,主页在http://www.bouncycastle.org/
            Security.addProvider(new BouncyCastleProvider());
        }
     
        /**
         * AES解密
         *
         * @param data           //密文,被加密的数据
         * @param key            //秘钥
         * @param iv             //偏移量
         * @param encodingFormat //解密后的结果需要进行的编码
         * @return
         * @throws Exception
         */
        public static JSONObject decrypt(String data, String key, String iv, String encodingFormat) throws Exception {
     
            //被加密的数据
            byte[] dataByte = Base64.decodeBase64(data);
            //加密秘钥
            byte[] keyByte = Base64.decodeBase64(key);
            //偏移量
            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;
                }
                
                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.parseObject(result);
                }
                return null;
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidParameterSpecException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    效果:

  • 相关阅读:
    minimum-path-sum
    pascals-triangle
    Java -- 二分查找
    redis缓存雪崩,击穿,穿透(copy)
    使用redis限制提交次数
    数据库的悲观锁和乐观锁
    mysql常用命令
    php压缩Zip文件和文件打包下载
    php去除数据库的数据空格
    php获取本年、本月、本周时间戳和日期格式的实例代码(分析)
  • 原文地址:https://www.cnblogs.com/eRrsr/p/14742069.html
Copyright © 2011-2022 走看看