zoukankan      html  css  js  c++  java
  • ~随笔A006~微信扫码的授权、用户绑定、关注公众号、消息反馈

      微信已变成我们生活、工作、社交、出行、娱乐的生活方式。这里总结下微信开发的基本功能。

      一、微信授权登录或访问第三方网站

        微信授权登录或访问第三方网站,需通过微信公众号来授权。

      (1)通过接口 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect进行授权登录

    	public static void wxBind(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// 引导用户进行相关授权,获取code
    		// 创建回调地址
    		String table=req.getParameter("table");
    		String shortUrl=req.getParameter("shortUrl");
    		ReadProperties pro = new ReadProperties();
    		Map<String, String> map = pro.getProperties();
    		String protocol = map.get("protocol");
    		String domain = map.get("domain");
    //		String port = map.get("port");
    		String project = map.get("project");
    		String backUrl = protocol + domain  + project + "wexinUtil.do?verify&table="+table+"&shortUrl="+shortUrl;
    		// https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
    		String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid=" + AuthUtil.APPID
    				+ "&redirect_uri=" + URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_userinfo" // 选择userinfo作用域
    				// +"&scope=snsapi_base" //选择userinfo作用域
    				+ "&state=STATE#wechat_redirect";
    		System.out.println("redirect_uri:" + URLEncoder.encode(backUrl));
    		resp.sendRedirect(url); // 请求重定向
    	}
    

      (2)授权成功后,会跳转到backUrl的地址

    	@RequestMapping(params = "verify")
    	protected Object verify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    		String table=req.getParameter("table");
    		String shortUrl=req.getParameter("shortUrl");
    		String code=req.getParameter("code");//获取OAuth2.0请求后,服务器返回的code内容,这个code在接下来向微信服务请求用户信息时会使用
    		System.out.println("code::::::::"+code);
    		//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    		String url="https://api.weixin.qq.com/sns/oauth2/access_token?"
    						+"appid="+AuthUtil.APPID
    						+"&secret="+AuthUtil.APPSECRET
    						+"&code="+code 
    						+"&grant_type=authorization_code"; 
    		 //发送请求
    		JSONObject jsonObject=AuthUtil.doGetJson(url);
    		System.out.println("jsonObject新获取::::::::"+jsonObject);
    		String openid=jsonObject.getString("openid");
    		String token=jsonObject.getString("access_token");
    		//判断用户是否关注公众号
    		String isFollow = judgeIsFollow(getAccessToken().getToken(),openid);
    		System.out.println("isFollow==="+isFollow);
    		//拉取用户信息路径
    		//https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
    		/*String infoUrl="https://api.weixin.qq.com/sns/userinfo?access_token="+token
    						+"&openid="+openid
    						+"&lang=zh_CN";
    		//发送请求
    		JSONObject userInfo=AuthUtil.doGetJson(infoUrl);
    		System.out.println("userInfo:"+userInfo);  */
    		//链接数据库查询
    		String sql =  "select user_code,operation,bind from user_mobile_er where openid='"+openid+"'";
    		
    		System.out.println("sql+++++++++"+sql);
    		   
    		List<Map<String, Object>> findList = systemService.findForJdbc(sql); 
    		System.out.println("findList+++++++++"+findList); 
    		System.out.println("openid===="+openid); 
    		  
    		String bind=null;
    		String operation=null;
    		if(findList!=null&&findList.size()>0){
    			operation= (String) findList.get(0).get("operation"); 
    			bind=(String) findList.get(0).get("bind");// 结果为Y/N
    		}else { 
    			bind="0";//用户未申请绑定
    			operation="0";//无维护权限
    		}
    	 System.out.println("redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl);
    		//return "redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl+"&openid="+openid+"&bind=Y";
    		return "redirect:/resftlCon.do?"+table+"&shortUrl="+shortUrl+"&isFollow="+isFollow+"&bind="+bind+"&operation="+operation+"&openid="+openid;
    	}

      二、微信用户与第三方平台绑定

        每个微信用户针对每个公众号有个唯一标识openid,我们可通过授权访问时获取的openID与数据库中存储的指定用户的openID进行对比

      三、判断否关注公众号(使用openID和access_token)

    	/**
    	 * 判断用户是否关注了公众号
    	 * @param token
    	 * @param openid
    	 * @return
    	 */
    	public static String judgeIsFollow(String token,String openid){
    	   // Integer subscribe=0;
    		 String subscribe=null;
    	        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+token+"&openid="+openid+"&lang=zh_CN";
    	    try {  
    	            URL urlGet = new URL(url);  
    	            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();  
    	            http.setRequestMethod("GET"); // 必须是get方式请求  
    	            http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");  
    	            http.setDoOutput(true);  
    	            http.setDoInput(true);  
    	            http.connect();  
    	            InputStream is = http.getInputStream();  
    	            int size = is.available();  
    	            byte[] jsonBytes = new byte[size];  
    	            is.read(jsonBytes);  
    	            String message = new String(jsonBytes, "UTF-8");  
    	            System.out.println("message字符串==="+message); 
    	            JSONObject demoJson = JSONObject.fromObject(message);  
    	            System.out.println("JSON字符串==="+demoJson); 
    	            subscribe=demoJson.get("subscribe").toString();
    	            //subscribe = demoJson.getInt("subscribe");
    	            System.err.println("subscribe在json中值为==="+subscribe);
    	            is.close();  
    	    } catch (Exception e) {  
    	            e.printStackTrace();  
    	    }
    	    //return 1==subscribe?true:false;
    	    return "1".equals(subscribe)?"Y":"N";
    	}
    

      通过接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+AuthUtil.APPID+"&secret="+AuthUtil.APPSECRET

    获取access_token

        /**
         * 获取AccessToken
         * @return 返回拿到的access_token及有效期
         */
        public static AccessToken getAccessToken() throws ClientProtocolException, IOException{
            AccessToken token = new AccessToken();
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+AuthUtil.APPID+"&secret="+AuthUtil.APPSECRET;
    		 
            JSONObject jsonObject = doGetStr(url);//使用刚刚写的doGet方法接收结果
            if(jsonObject!=null){ //如果返回不为空,将返回结果封装进AccessToken实体类
                token.setToken(jsonObject.getString("access_token"));//取出access_token
                token.setExpiresIn(jsonObject.getInt("expires_in"));//取出access_token的有效期
            }
            System.out.println("==============token:"+token.getToken()+"expiresIn:"+token.getExpiresIn());
            return token;
        }
        /**
         * 编写Get请求的方法。但没有参数传递的时候,可以使用Get请求
         * 
         * @param url 需要请求的URL
         * @return 将请求URL后返回的数据,转为JSON格式,并return
         */
        public static JSONObject doGetStr(String url) throws ClientProtocolException, IOException {
            DefaultHttpClient client = new DefaultHttpClient();//获取DefaultHttpClient请求
            HttpGet httpGet = new HttpGet(url);//HttpGet将使用Get方式发送请求URL
            JSONObject jsonObject = null;
            HttpResponse response = client.execute(httpGet);//使用HttpResponse接收client执行httpGet的结果
            HttpEntity entity = response.getEntity();//从response中获取结果,类型为HttpEntity
            if(entity != null){
                String result = EntityUtils.toString(entity,"UTF-8");//HttpEntity转为字符串类型
                jsonObject = JSONObject.fromObject(result);//字符串类型转为JSON类型
            }
            return jsonObject;
        }
    

      

      AccessToken的实体类

    package com.jeecg.util.wxBind;
    
    public class AccessToken {
    	public String token;
    	public int expiresIn;
    	public String getToken() {
    		return token;
    	}
    	public void setToken(String token) {
    		this.token = token;
    	}
    	public int getExpiresIn() {
    		return expiresIn;
    	}
    	public void setExpiresIn(int expiresIn) {
    		this.expiresIn = expiresIn;
    	} 
    }
    

     

      四、第三方平台对指定用户进行消息推送(需要使用weixin4j.jar)

        使用接口https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+oAuthToken.getAccess_token()

    进行推送;消息推送的前提是该指定用户已关注认证公众号。

    package com.jeecg.util.wxBind;
    
    import java.net.URLEncoder;
    import java.util.Map;
    
    import org.weixin4j.Configuration;
    import org.weixin4j.Weixin;
    import org.weixin4j.WeixinException;
    import org.weixin4j.WeixinSupport;
    import org.weixin4j.http.HttpsClient;
    import org.weixin4j.http.OAuthToken;
    import org.weixin4j.http.Response;
    
    import com.alibaba.fastjson.JSONObject;
    import com.jeecg.controller.demo.ReadProperties;
    import com.jeecg.controller.wx.auth.util.AuthUtil;
     
    public class WeixinMessagePush extends WeixinSupport { 
        Weixin weixin=new Weixin();
        OAuthToken oAuthToken=null;
        public WeixinMessagePush(){
    
        }
    
        public WeixinMessagePush(String appId,String secret){
    
            try {
                oAuthToken = weixin.login(appId, secret);
            } catch (WeixinException e) {
                e.printStackTrace();
            }
        }
        public void templateMessagePush(String openId,String title,String description) throws WeixinException{
            JSONObject json=new JSONObject();
            JSONObject text=new JSONObject();
            JSONObject keyword1=new JSONObject();
            JSONObject keyword2=new JSONObject();
            JSONObject first=new JSONObject();
            JSONObject remark=new JSONObject();
            json.put("touser",openId);
            json.put("template_id","jhES0sm0yRNXxe8USlYcB1nsaS568gtFt7l6_qCY4_8");
        	ReadProperties pro = new ReadProperties();
        	Map<String, String> map = pro.getProperties();
    		String protocol = map.get("protocol");
    		String domain = map.get("domain");
    //		String port = map.get("port");
    		String project = map.get("project");
    		String backUrl = protocol + domain  + project + "userMobileErController.do?remark";
    		
            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + "appid=" + AuthUtil.APPID
    				+ "&redirect_uri=" + URLEncoder.encode(backUrl) + "&response_type=code" + "&scope=snsapi_userinfo" // 选择userinfo作用域
    		// +"&scope=snsapi_base" //选择userinfo作用域
    				+ "&state=STATE#wechat_redirect";
          //  json.put("url", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx22c699fe80c91471&redirect_uri=http%3A%2F%2Fwewill9014.s1.natapp.cc%2FPTCOA%2Fservlet%2FOAuthAPIServlet&response_type=code&scope=snsapi_userinfo&state=state#wechat_redirect");
            json.put("utl", url);
            json.put("topcolor","#ff1a75");
            first.put("value",title);
    //      first.put("color","#007f80");
            keyword1.put("value",description );
    //      keyword1.put("color", "#007f80");
            keyword2.put("value","通过" );
    //      keyword2.put("color","#007f80");
            remark.put("value", "如有疑问请联系管理员");
            remark.put("color", "#007f80");
            text.put("keyword1", keyword1);
            text.put("keyword2", keyword2);
            text.put("first", first);
            text.put("remark",remark);
            json.put("data", text);
    
            //创建请求对象
            HttpsClient http=new HttpsClient();
            Response res = http.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+oAuthToken.getAccess_token(), json);
             //根据请求结果判定,是否验证成功
            JSONObject jsonObj = res.asJSONObject();
            if (jsonObj != null) {
                if (Configuration.isDebug()) {
                    System.out.println("模板消息返回json:" + jsonObj.toString());
                }
                Object errcode = jsonObj.get("errcode");
                if (errcode != null && !errcode.toString().equals("0")) {
                    //返回异常信息
                    throw new WeixinException(getCause(Integer.parseInt(errcode.toString())));
                }
            }   
        }   
    }
    

      

  • 相关阅读:
    zookeeper基本知识
    kafka常见问题
    模板设计模式
    Zookeeper的未授权访问漏洞解决
    Kubernetes准入控制器PodNodeSelector、PodTolerationRestriction
    Kubernetes 基于 Namespace 的物理队列实现,即Namespace下的Pod和Node的强绑定
    银行卡LUHM校验算法(C++)(转)
    银行卡LUHM校验算法(C++)(转)
    Unity导弹自动追踪算法(转)
    基于MicroChip ATmega4808的阿里云IOT连接开发套件方案(转)
  • 原文地址:https://www.cnblogs.com/gaojl/p/8405186.html
Copyright © 2011-2022 走看看