精华内容
下载资源
问答
  • 微信小程序java后端代码
  • 微信小程序java后台代码(服务端)demo
  • 微信小程序java解密demospringboot-weapp-demo-master.zip
  • 微信小程序后端代码,简单的后台程序,基于SPRINGBOOT搭建的后台程序,前端发送请求,后台响应...............
  • 微信小程序 java设置cookie登录 wx.request()发起的每次请求对于服务器来说都是不同的会话 这样导致后续请求都相当于未登录的状态。 app.js globalData: { url: ‘http://127.0.0.1:8080’, cookie: “”, }, 后台 @...

    微信小程序 java设置cookie登录
    wx.request()发起的每次请求对于服务器来说都是不同的会话 这样导致后续请求都相当于未登录的状态。
    app.js
    globalData: {
    url: ‘http://127.0.0.1:8080’,
    cookie: “”,

    },
    后台

    @PostMapping(“sessionId”)
    @ResponseBody`

    public String sessionId( HttpServletRequest request){
    		String sessionId=request.getSession().getId();
    		return sessionId;
    	}
    

    返回给前台
    前台在请求的回调中给全局的参数cookie赋值

     onLoad: function(options) {
        wx.request({
          url: url,
          method: 'post',
          success(res) {
            app.globalData.cookie = 'JSESSIONID=' + res.data
            console.log(app.globalData.cookie)
          }
        })
      },
    

    然后在每次请求request的header中添加

     header: {
                   ....,
                   'cookie': getApp().globalData.cookie
              },
    
    展开全文
  • 微信小程序Java登录流程

    万次阅读 多人点赞 2018-05-10 15:05:04
    一、登录流程图二、微信小程序端doLogin:function(callback = () =>{}){ let that = this; wx.login({ success:function(loginRes){ if(loginRes){ //获取用户信息 wx.getUserInfo({ withCredentials:...

    一、登录流程图

    二、微信小程序端

    doLogin:function(callback = () =>{}){
    let that = this;
    wx.login({
      success:function(loginRes){
        if(loginRes){
          //获取用户信息
          wx.getUserInfo({
            withCredentials:true,//非必填  默认为true
            success:function(infoRes){
              console.log(infoRes,'>>>');
              //请求服务端的登录接口
              wx.request({
                url: api.loginUrl,
                data:{
                  code:loginRes.code,//临时登录凭证
                  rawData:infoRes.rawData,//用户非敏感信息
                  signature:infoRes.signature,//签名
                  encrypteData:infoRes.encryptedData,//用户敏感信息
                  iv:infoRes.iv//解密算法的向量
                },
                success:function(res){
                  console.log('login success');
                  res = res.data;
                  if(res.result==0){
                    that.globalData.userInfo = res.userInfo;
                    wx.setStorageSync('userInfo',JSON.stringify(res.userInfo));
                    wx.setStorageSync('loginFlag',res.skey);
                    console.log("skey="+res.skey);
                    callback();
                  }else{
                    that.showInfo('res.errmsg');
                  }
                },
                fail:function(error){
                  //调用服务端登录接口失败
                 // that.showInfo('调用接口失败');
                  console.log(error);
                }
              });
            }
          });
        }else{
    
        }
      }
    });
    }
    

    微信小程序端发起登录请求,携带的参数主要有:

        code:loginRes.code,//临时登录凭证
        rawData:infoRes.rawData,//用户非敏感信息
        signature:infoRes.signature,//签名
        encrypteData:infoRes.encryptedData,//用户敏感信息
        iv:infoRes.iv//解密算法的向量
    

    需要的数据主要有:

    result、userInfo和skey
    

    result用来判断是否登录成功,userInfo是用户的一些信息,保存在缓存中,不用每次都从后台获取,skey是用户登录态标识,也放在缓存中,如果skey存在就直接登录,维护用户的登录状态,具有时效性

    三、Java后台

    @ResponseBody
    @RequestMapping("/login")
    public Map<String,Object> doLogin(Model model,
                                      @RequestParam(value = "code",required = false) String code,
                                      @RequestParam(value = "rawData",required = false) String rawData,
                                      @RequestParam(value = "signature",required = false) String signature,
                                      @RequestParam(value = "encrypteData",required = false) String encrypteData,
                                      @RequestParam(value = "iv",required = false) String iv){
        log.info( "Start get SessionKey" );
    
    
        Map<String,Object> map = new HashMap<String, Object>(  );
        System.out.println("用户非敏感信息"+rawData);
    
        JSONObject rawDataJson = JSON.parseObject( rawData );
    
        System.out.println("签名"+signature);
        JSONObject SessionKeyOpenId = getSessionKeyOrOpenId( code );
        System.out.println("post请求获取的SessionAndopenId="+SessionKeyOpenId);
    
        String openid = SessionKeyOpenId.getString("openid" );
    
        String sessionKey = SessionKeyOpenId.getString( "session_key" );
    
        System.out.println("openid="+openid+",session_key="+sessionKey);
    
        User user = userService.findByOpenid( openid );
        //uuid生成唯一key
        String skey = UUID.randomUUID().toString();
        if(user==null){
            //入库
            String nickName = rawDataJson.getString( "nickName" );
            String avatarUrl = rawDataJson.getString( "avatarUrl" );
            String gender  = rawDataJson.getString( "gender" );
            String city = rawDataJson.getString( "city" );
            String country = rawDataJson.getString( "country" );
            String province = rawDataJson.getString( "province" );
    
    
            user = new User();
            user.setUid( openid );
            user.setCreateTime( new Date(  ) );
            user.setSessionkey( sessionKey );
            user.setUbalance( 0 );
            user.setSkey( skey );
            user.setUaddress( country+" "+province+" "+city );
            user.setUavatar( avatarUrl );
            user.setUgender( Integer.parseInt( gender ) );
            user.setUname( nickName );
            user.setUpdateTime( new Date(  ) );
    
            userService.insert( user );
        }else {
            //已存在
            log.info( "用户openid已存在,不需要插入" );
        }
        //根据openid查询skey是否存在
        String skey_redis = (String) redisTemplate.opsForValue().get( openid );
        if(StringUtils.isNotBlank( skey_redis )){
            //存在 删除 skey 重新生成skey 将skey返回
            redisTemplate.delete( skey_redis );
    
        }
            //  缓存一份新的
            JSONObject sessionObj = new JSONObject(  );
            sessionObj.put( "openId",openid );
            sessionObj.put( "sessionKey",sessionKey );
            redisTemplate.opsForValue().set( skey,sessionObj.toJSONString() );
            redisTemplate.opsForValue().set( openid,skey );
    
            //把新的sessionKey和oppenid返回给小程序
            map.put( "skey",skey );
    
    
    
        map.put( "result","0" );
    
    
    
        JSONObject userInfo = getUserInfo( encrypteData, sessionKey, iv );
        System.out.println("根据解密算法获取的userInfo="+userInfo);
        userInfo.put( "balance",user.getUbalance() );
        map.put( "userInfo",userInfo );
    
        return map;
    }
    

    获取openid和sessionKey方法

    public static JSONObject getSessionKeyOrOpenId(String code){
        //微信端登录code
        String wxCode = code;
        String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
        Map<String,String> requestUrlParam = new HashMap<String, String>(  );
        requestUrlParam.put( "appid","你的小程序appId" );//小程序appId
        requestUrlParam.put( "secret","你的小程序appSecret" );
        requestUrlParam.put( "js_code",wxCode );//小程序端返回的code
        requestUrlParam.put( "grant_type","authorization_code" );//默认参数
    
        //发送post请求读取调用微信接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject( UrlUtil.sendPost( requestUrl,requestUrlParam ));
        return jsonObject;
    }
    

    解密用户敏感数据获取用户信息

    public static JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){
        // 被加密的数据
        byte[] dataByte = Base64.decode(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decode(sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decode(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 JSON.parseObject(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;
    }

    四、流程

    1.小程序端发起请求并携带主要参数

    2.java后台接到/login请求后,根据code去调用微信接口获取用户唯一标识openid和sessionKey

    3.根据openid查询mysql数据库,判断该用户是否存在,如果不存在将用户非敏感信息和其他初始化数据存入到数据库中,如果已存在,不操作

    4.根据openid查询redis数据库,判断openid对应的skey是否存在,如果存在则删除原来老的skey以及对应的openid和sessionKey

    5.通过uuid生成唯一的skey,用openid做键,skey做值,存入到redis中

    6.然后把skey做键,openid和sessionKey的json串做值也重新存入到redis中

    7.根据解密算法,参数有encryptedData、sessionKey和iv,获取用户信息userInfo,如果userInfo字段不满足需要,可通过userInfo.put( "balance",user.getUbalance() );添加所需要的字段和值

    8.将微信小程序需要的数据封装到map中,返回给小程序端

    map.put( "skey",skey );
    
    map.put( "result","0" );
    
    map.put( "userInfo",userInfo ); 
    
    return map;

    更多博客内容详见我的博客 Wang's Blog

    展开全文
  • 有助于写微信小程序的小伙伴们 进行前端与后端的交互的代码。
  • 微信小程序java后台解码获取信息

    千次阅读 2018-01-24 13:44:28
    微信小程序java后台解码获取信息 由于小程序开发多个地方都需要使用到解码获取信息的需求,但由于本人从事java的开发然后去官网下载的sdk中竟然没有java的。哎-_-。所以准备写一篇关于java解码的blog吧。 一、...

    微信小程序java后台解码获取信息

    由于小程序开发多个地方都需要使用到解码获取信息的需求,但由于本人从事java的开发然后去官网下载的sdk中竟然没有java的。哎-_-。所以准备写一篇关于java解码的blog吧。

    一、我们解码前需要获取到几个小程序前端传过来的数据
    登录凭证code:调用wx.login()可以获得;
    秘钥iv和需要解码的encryptedData字符串:这个根据自己项目的需求定了,比如:获取openid和unionid可以在 wx.getUserInfo()中获得iv和encryptedData。
    如果获取微信群ID:则通过wx.getShareInfo()获得iv和encryptedData。
    微信小程序前端这里就不做详细的分析了。

    二 、 java后端的实现

    /**
         * 获取微信群ID(Gid)
         * data:2018/1/24
         * @return
         * @throws Exception 
         */
        public String wxGetGroupGid() throws Exception{
    
            String code=request.getParameter("code");接受小程序传过来的登录凭证code,
            String iv=request.getParameter("iv");
            String encryptedData=request.getParameter("encryptedData");
            String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret"
                    + "=SECRET&js_code=JSCODE&grant_type=authorization_code";// 获取openid的地址
            String url = OPENID_URL.replace("APPID", Pkcs7Encoder.APPID)
                    .replace("SECRET", Pkcs7Encoder.APPSECRET)
                    .replace("JSCODE", code);
            JSONObject jsonObject = null;
            //向微信后台发起请求的url 
            jsonObject = Pkcs7Encoder.doGetStr(url);// 调取Get提交方法
            String session_key = jsonObject.getString("session_key");
            String result = Pkcs7Encoder.decrypt(encryptedData, session_key, iv,
                    "UTF-8");
    
            JSONObject userInfoJSON = JSONObject.fromObject(result);
            String openGid=userInfoJSON.getString("openGId");
            System.out.println(openGid);
            String JData="{\"openGid\":\""+openGid+"\"}";
            //response.getWriter().write(openGid);
            Struts2Utils.renderJsonNoDown(response, JData); 
            return null;
        }

    解码的帮助类

    public class Pkcs7Encoder {
         public final static String APPID = "***";   //小程序的APPID
          public final static   String APPSECRET = "***"; //小程序的appsecret
         public final static String grant_type = "authorization_code";//授权(必填)
          // 算法名称
        static  final String KEY_ALGORITHM = "AES";
        // 加解密算法/模式/填充方式
        static  final String algorithmStr = "AES/CBC/PKCS7Padding";
        private static Key key;
        private static Cipher cipher;
        boolean isInited = false;
    
        //默认对称解密算法初始向量 iv
        static byte[] iv = { 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, 0x30, 0x38 };
    
    
        public static String decrypt(String encryptedData, String sessionKey, String iv, String encodingFormat)
                throws Exception {
                // 被加密的数据
                byte[] dataByte = Base64.decode(encryptedData);
                // 加密秘钥
                byte[] keyByte = Base64.decode(sessionKey);
                // 偏移量
                byte[] ivByte = Base64.decode(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");
                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).toString();
                }
                }catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
        }
        /**
         * 返回openid,unionid
         * @param url
         * @return
         */
        public static JSONObject doGetStr(String url){
    
            DefaultHttpClient httpClient = new DefaultHttpClient();
    
            HttpGet httpGet = new HttpGet(url);
    
            JSONObject jsonObject = null;
    
            try {
                HttpResponse response = httpClient.execute(httpGet);
    
                HttpEntity entity = response.getEntity();   //接受结果
                if(entity != null){
                    String result = EntityUtils.toString(entity,"UTF-8");
                    jsonObject = JSONObject.fromObject(result);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return jsonObject;
        }
    
        public static void init(byte[] keyBytes) {
    
            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyBytes.length % base != 0) {
                int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
                keyBytes = temp;
            }
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            // 转化成JAVA的密钥格式
            key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
            try {
                // 初始化cipher
                cipher = Cipher.getInstance(algorithmStr, "BC");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchProviderException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        /**
         * 加密方法
         *      --使用默认iv时
         * @param content
         *            要加密的字符串
         * @param keyBytes
         *            加密密钥
         * @return
         */
        public static byte[] encrypt(byte[] content, byte[] keyBytes) {
            byte[] encryptedText =  encryptOfDiyIV(content,keyBytes,iv);
            return encryptedText;
        }
    
    
        /**
         * 解密方法
         *      --使用默认iv时
         * @param encryptedData
         *            要解密的字符串
         * @param keyBytes
         *            解密密钥
         * @return
         */
        public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) {
            byte[] encryptedText = decryptOfDiyIV(encryptedData,keyBytes,iv);
            return encryptedText;
        }
        /**
         * 加密方法
         *      ---自定义对称解密算法初始向量 iv
         * @param content
         *              要加密的字符串
         * @param keyBytes
         *              加密密钥
         * @param ivs
         *         自定义对称解密算法初始向量 iv
         * @return 加密的结果
         */
        public static byte[] encryptOfDiyIV(byte[] content, byte[] keyBytes, byte[] ivs) {
            byte[] encryptedText = null;
            init(keyBytes);
            System.out.println("IV:" + new String(ivs));
            try {
                cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivs));
                encryptedText = cipher.doFinal(content);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return encryptedText;
        }
        /**
         * 解密方法
         *
         * @param encryptedData
         *            要解密的字符串
         * @param keyBytes
         *            解密密钥
         * @param ivs
         *         自定义对称解密算法初始向量 iv
         * @return
         */
        public static byte[] decryptOfDiyIV(byte[] encryptedData, byte[] keyBytes,byte[] ivs) {
            byte[] encryptedText = null;
            init(keyBytes);
            System.out.println("IV:" + new String(ivs));
            try {
                cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(ivs));
                encryptedText = cipher.doFinal(encryptedData);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return encryptedText;
        }
        /** 
    * 向指定 URL 发送POST方法的请求 
    *  
    * @param url 发送请求的 URL 
    * @param param 请求参数 
    * @return 所代表远程资源的响应结果 
    */  
    public static String sendPost(String url, Map<String, ?> paramMap) {  
         PrintWriter out = null;  
         BufferedReader in = null;  
         String result = "";  
    
         String param = "";  
    Iterator<String> it = paramMap.keySet().iterator();  
    
    while(it.hasNext()) {  
       String key = it.next();  
       param += key + "=" + paramMap.get(key) + "&";  
    }  
    
         try {  
             URL realUrl = new URL(url);  
             // 打开和URL之间的连接  
             URLConnection conn = realUrl.openConnection();  
             // 设置通用的请求属性  
             conn.setRequestProperty("accept", "*/*");  
             conn.setRequestProperty("connection", "Keep-Alive");  
             conn.setRequestProperty("Accept-Charset", "utf-8");  
             conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");  
             // 发送POST请求必须设置如下两行  
             conn.setDoOutput(true);  
             conn.setDoInput(true);  
             // 获取URLConnection对象对应的输出流  
             out = new PrintWriter(conn.getOutputStream());  
             // 发送请求参数  
             out.print(param);  
             // flush输出流的缓冲  
             out.flush();  
             // 定义BufferedReader输入流来读取URL的响应  
             in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));  
             String line;  
             while ((line = in.readLine()) != null) {  
                 result += line;  
             }  
         } catch (Exception e) {  
          e.printStackTrace();
         }  
         //使用finally块来关闭输出流、输入流  
         finally{  
             try{  
                 if(out!=null){  
                     out.close();  
                 }  
                 if(in!=null){  
                     in.close();  
                 }  
             }  
             catch(IOException ex){  
                 ex.printStackTrace();  
             }  
         }  
         return result;  
     }  
    
    }

    只要涉及到小程序解码的都是通用的,所以到这里已经完成了。

    展开全文
  • 微信小程序java登录授权解密获取unionId(填坑) 2018年08月03日 16:00:18 人类电影精华丶 阅读数 4041 官方流程图: 第一步:获取code 说明: 小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。 ...

    微信小程序java登录授权解密获取unionId(填坑)
    2018年08月03日 16:00:18 人类电影精华丶 阅读数 4041
    官方流程图:

    第一步:获取code

    说明:

    小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。

    开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。

    之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

    //app.js
    App({
    onLaunch: function() {
    wx.login({
    success: function(res) {
    if (res.code) {
    //发起网络请求
    wx.request({
    url: ‘https://test.com/onLogin’,
    data: {
    code: res.code
    }
    })
    } else {
    console.log(‘登录失败!’ + res.errMsg)
    }
    }
    });
    }
    })

    关于unionId,这里需要说明一下,如果应用只限于小程序内则不需要unionId,直接通过openId可以确定用户身份,但是如果需要跨应用 如:网页应用,app应用时则需要使用到unionId作为身份标识。

    UnionID获取途径

    绑定了开发者帐号的小程序,可以通过下面3种途径获取UnionID。

    调用接口wx.getUserInfo,从解密数据中获取UnionID。注意本接口需要用户授权,请开发者妥善处理用户拒绝授权后的情况。

    如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。开发者可以直接通过wx.login获取到该用户UnionID,无须用户再次授权。

    如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。开发者也可以直接通过wx.login获取到该用户UnionID,无须用户再次授权。

    说明完了,我们继续下一步,主要需要区分获得授权,和未获得授权情况

    第二步:通过code换取sessionKey等个人信息

    1、未获得授权

      注意:这里unionId如果满足上面2、3所说获取条件,则会在这一步里返回,如果不满足则需要调用wx.getUserInfo来获取,这个方法需要获得用户授权。
    

    public class Test {

    private static final String APPID = "";// 微信应用唯一标识
    private static final String SECRET = "";
    
    public void main(String code) {
    
    	JSONObject jsonObject = code2sessionKey(code);
    
    	String openId = jsonObject.getString("openid");// 用户唯一标识
    
    	String session_key = jsonObject.getString("session_key");// 密钥
    
    	// 满足UnionID下发条件的情况下,返回
    	String unionId = jsonObject.getString("unionid");
    
    }
    
    /**
     * 发送请求用code换取sessionKey和相关信息
     * 
     * @param code
     * @return
     */
    public static JSONObject code2sessionKey(String code) {
    	String stringToken = String.format(
    			"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
    			APPID, SECRET, code);
    	String response = HttpUtils.httpsRequestToString(stringToken, "GET", null);
    	return JSON.parseObject(response);
    }
    
    /**
     * 发送https请求
     * 
     * @param path
     * @param method
     * @param body
     * @return
     */
    public static String httpsRequestToString(String path, String method, String body) {
    	if (path == null || method == null) {
    		return null;
    	}
    	String response = null;
    	InputStream inputStream = null;
    	InputStreamReader inputStreamReader = null;
    	BufferedReader bufferedReader = null;
    	HttpsURLConnection conn = null;
    	try {
    		// 创建SSLConrext对象,并使用我们指定的信任管理器初始化
    		SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
    		TrustManager[] tm = { new X509TrustManager() {
    			@Override
    			public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    			}
    
    			@Override
    			public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    			}
    
    			@Override
    			public X509Certificate[] getAcceptedIssuers() {
    				return null;
    			}
    
    		} };
    		sslContext.init(null, tm, new java.security.SecureRandom());
    
    		// 从上面对象中得到SSLSocketFactory
    		SSLSocketFactory ssf = sslContext.getSocketFactory();
    
    		URL url = new URL(path);
    		conn = (HttpsURLConnection) url.openConnection();
    		conn.setSSLSocketFactory(ssf);
    
    		conn.setDoOutput(true);
    		conn.setDoInput(true);
    		conn.setUseCaches(false);
    
    		// 设置请求方式(get|post)
    		conn.setRequestMethod(method);
    
    		// 有数据提交时
    		if (null != body) {
    			OutputStream outputStream = conn.getOutputStream();
    			outputStream.write(body.getBytes("UTF-8"));
    			outputStream.close();
    		}
    
    		// 将返回的输入流转换成字符串
    		inputStream = conn.getInputStream();
    		inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
    		bufferedReader = new BufferedReader(inputStreamReader);
    		String str = null;
    		StringBuffer buffer = new StringBuffer();
    		while ((str = bufferedReader.readLine()) != null) {
    			buffer.append(str);
    		}
    
    		response = buffer.toString();
    	} catch (Exception e) {
    
    	} finally {
    		if (conn != null) {
    			conn.disconnect();
    		}
    		try {
    			bufferedReader.close();
    			inputStreamReader.close();
    			inputStream.close();
    		} catch (IOException execption) {
    
    		}
    	}
    	return response;
    }
    

    }

    2、获得授权情况下

    当前台获得了用户的授权后,我们就可以获得用户的个人信息以及unionId(不管有没有关注公众号)

    前台接口:

    wx.getUserInfo(OBJECT)
    注意:此接口有调整,使用该接口将不再出现授权弹窗,请使用 引导用户主动进行授权操作

    当用户未授权过,调用该接口将直接报错
    当用户授权过,可以使用该接口获取用户信息
    OBJECT参数说明:

    参数名 类型 必填 说明 最低版本
    withCredentials Boolean 否 是否带上登录态信息 1.1.0
    lang String 否 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。默认为en。 1.3.0
    timeout Number 否 超时时间,单位 ms 1.9.90
    success Function 否 接口调用成功的回调函数
    fail Function 否 接口调用失败的回调函数
    complete Function 否 接口调用结束的回调函数(调用成功、失败都会执行)
    注:当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。

    success返回参数说明:

    参数 类型 说明
    userInfo OBJECT 用户信息对象,不包含 openid 等敏感信息
    rawData String 不包括敏感信息的原始数据字符串,用于计算签名。
    signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档 signature。
    encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法
    iv String 加密算法的初始向量,详细见加密数据解密算法

    示例代码:


    授权登录
    请升级微信版本
    //js
    Page({
    data: {
    canIUse: wx.canIUse(‘button.open-type.getUserInfo’)
    },
    onLoad: function() {
    // 查看是否授权
    wx.getSetting({
    success: function(res){
    if (res.authSetting[‘scope.userInfo’]) {
    // 已经授权,可以直接调用 getUserInfo 获取头像昵称
    wx.getUserInfo({
    success: function(res) {
    console.log(res.userInfo)
    }
    })
    }
    }
    })
    },
    bindGetUserInfo: function(e) {
    console.log(e.detail.userInfo)
    }
    })
    前台调用getUserInfo后,可以将获得的code值,encryptedData加密数据包,iv初始向量提示发给后台

    后台代码如下:

    public class Test {

    private static final String APPID = "";// 微信应用唯一标识
    private static final String SECRET = "";
    
    public void main(String code,String encryptedData,String iv) {
    
    	JSONObject jsonObject = code2sessionKey(code);
    
    	String openId = jsonObject.getString("openid");// 用户唯一标识
    
    	String session_key = jsonObject.getString("session_key");// 密钥
    
    	// 解密encryptedData,获取unionId相关信息
    	JSONObject json = decryptionUserInfo(encryptedData, session_key, iv);
    }
    
    /**
     * 发送请求用code换取sessionKey和相关信息
     * 
     * @param code
     * @return
     */
    public static JSONObject code2sessionKey(String code) {
    	String stringToken = String.format(
    			"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
    			APPID, SECRET, code);
    	String response = HttpUtils.httpsRequestToString(stringToken, "GET", null);
    	return JSON.parseObject(response);
    }
    /**
     * 小程序解密用户数据
     * 
     * @param encryptedData
     * @param sessionKey
     * @param iv
     * @return
     */
    public static JSONObject decryptionUserInfo(String encryptedData, String sessionKey, String iv) {
    	// 被加密的数据
    	byte[] dataByte = Base64.decode(encryptedData);
    	// 加密秘钥
    	byte[] keyByte = Base64.decode(sessionKey);
    	// 偏移量
    	byte[] ivByte = Base64.decode(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.parseObject(result);
    			
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return null;
    }
    /**
     * 发送https请求
     * 
     * @param path
     * @param method
     * @param body
     * @return
     */
    public static String httpsRequestToString(String path, String method, String body) {
    	if (path == null || method == null) {
    		return null;
    	}
    	String response = null;
    	InputStream inputStream = null;
    	InputStreamReader inputStreamReader = null;
    	BufferedReader bufferedReader = null;
    	HttpsURLConnection conn = null;
    	try {
    		// 创建SSLConrext对象,并使用我们指定的信任管理器初始化
    		SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
    		TrustManager[] tm = { new X509TrustManager() {
    			@Override
    			public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    			}
    
    			@Override
    			public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    			}
    
    			@Override
    			public X509Certificate[] getAcceptedIssuers() {
    				return null;
    			}
    
    		} };
    		sslContext.init(null, tm, new java.security.SecureRandom());
    
    		// 从上面对象中得到SSLSocketFactory
    		SSLSocketFactory ssf = sslContext.getSocketFactory();
    
    		URL url = new URL(path);
    		conn = (HttpsURLConnection) url.openConnection();
    		conn.setSSLSocketFactory(ssf);
    
    		conn.setDoOutput(true);
    		conn.setDoInput(true);
    		conn.setUseCaches(false);
    
    		// 设置请求方式(get|post)
    		conn.setRequestMethod(method);
    
    		// 有数据提交时
    		if (null != body) {
    			OutputStream outputStream = conn.getOutputStream();
    			outputStream.write(body.getBytes("UTF-8"));
    			outputStream.close();
    		}
    
    		// 将返回的输入流转换成字符串
    		inputStream = conn.getInputStream();
    		inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
    		bufferedReader = new BufferedReader(inputStreamReader);
    		String str = null;
    		StringBuffer buffer = new StringBuffer();
    		while ((str = bufferedReader.readLine()) != null) {
    			buffer.append(str);
    		}
    
    		response = buffer.toString();
    	} catch (Exception e) {
    
    	} finally {
    		if (conn != null) {
    			conn.disconnect();
    		}
    		try {
    			bufferedReader.close();
    			inputStreamReader.close();
    			inputStream.close();
    		} catch (IOException execption) {
    
    		}
    	}
    	return response;
    }
    

    }
    与未授权情况下,多了一步解密数据包的动作,解密后就能获得我们需要的数据啦,所以在处理登录时一定要考虑好用户授权情况。

    附:encryptedData 解密后 json 结构

    {
    “openId”: “OPENID”,
    “nickName”: “NICKNAME”,
    “gender”: GENDER,
    “city”: “CITY”,
    “province”: “PROVINCE”,
    “country”: “COUNTRY”,
    “avatarUrl”: “AVATARURL”,
    “unionId”: “UNIONID”,
    “watermark”:
    {
    “appid”:“APPID”,
    “timestamp”:TIMESTAMP
    }
    }

    (填坑…) 注意:上述返回的结果中如果还是没有unionId,这个时候需要检查是否完成开发者资质认证…

    微信开放平台绑定小程序流程

    前提:微信开放平台帐号必须已完成开发者资质认证

    开发者资质认证流程:

    登录微信开放平台(open.weixin.qq.com) – 帐号中心 – 开发者资质认证

    img

    绑定流程:

    登录微信开放平台(open.weixin.qq.com)—管理中心—公众帐号—绑定公众帐号

    img

    展开全文
  • java小程序代码1,通过ODBC连接import java.sql.*;public class ODBCTest {public static void main(String[] args) {Connection con = null;try {// 加载ODBC驱动(1) Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")...
  • 微信小程序java开发流程分享

    万次阅读 2017-06-05 08:54:51
    前段时间,我接触了微信的开发小程序,在开发过程中,我不得不承认微信小程序开发的简单粗暴,不多说,直接hight。 微信小程序可以去公众平台下载。有64位和32位的。在这里我就不多哔哔了。 下载完微信小程序后,...
  • 目录 最新版表白墙博客地址 ...1、微信小程序前台展示 2、功能介绍 3、后台管理 4、后端语言采用 JAVA 开发 5、体验此微信小程序 扫描下方二维码 6、如何联系我或需要源码进行联系 最新版表白墙博客地址 ...
  • 使用java8 java7 java6 解密微信小程序encryptedData可以回遇到一些错误 1.java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding 2.Java.security....
  • 分为小程序,开发者服务器(java端),微信接口服务(获取openid的接口) 小程序端: var that = this wx.login({ success: function (res) { var code = res.code;//发送给服务器的code if (code) { ...
  • 微信小程序java开发图片上传 ssm框架

    千次阅读 2018-05-12 09:13:44
    微信小程序图片上传与pc端图片上传是不同的,话不多说直接上代码:(复制粘贴可用)微信小程序端:chooseImage(){ wx.chooseImage({ success: function (res) { var tempFilePaths = res.tempFilePaths wx....
  • 最近在学习小程序,做个笔记,希望和大家相互交流学习 小程序地图导航,显示天气源码 https://github.com/zzwwjjdj319/miniProgramAmap ... 微信小程序机票查询源码:https://gitee.com/sccqcd/ticket_i...
  • 前几天要做一个信息小程序获取用户的手机号码的功能,但是发现,拿到的数据都是加密的,官方并没有提供Java后台的源代码。。。找到了很久,看到这篇文章,学习了,然后在这基础上做了一些修改,emmm是一些修改。 ...
  • 微信小程序开发相对没有微信公众号开发复杂,后台只需部分设置配置即可。 1.基本开发设置: 2.模板消息设置 小程序消息模板比公众号消息模板更为"死板",没有first头和remake备注参数,所以尽量选择最相近...
  • javaSSM写的后台,前端有一些页面是在网上找了几个。小程序里面一切文字图片都是从后台里面上传,还可以二次开发。 此为上线小程序商城,...150元出售,带java后台,mysql数据,带经销存系统,小程序后台系统...
  • 微信小程序Java解密AES加密数据

    千次阅读 2018-07-25 11:55:54
    微信demo下载下来发现没有Java版本,只能再找资料解密 我的Java解密代码是这样写的,可以用 import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java...
  • 微信小程序获取个人标识用如图的参数(https://img-ask.csdn.net/upload/201812/05/1543998324_564696.png) 利用下图的方法 之前不报错 今天突然报错![图片说明]...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,357
精华内容 1,742
关键字:

微信小程序java

java 订阅
微信小程序 订阅