主要原理:

1.从微信公众号发来的get请求为验证服务器安全性的

2.从微信公众号发来的post请求为接受和回复用户信息的

3.先根据是否有code来进行判断,如果有code的话,根据code换取openid,如果没有code的话,发送请求到微信授权页,微信授权页会带着code转发到当前的页面,然后根据code换取openid

package cn.jbolt.wx;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.jfinal.core.Controller;
import com.jfinal.plugin.redis.Redis;

import cn.jbolt.utils.HttpClientUtils;
import cn.jbolt.wx.model.WxReurnMap;
import net.sf.json.JSONObject;
 
public class wxController extends Controller {

public static String TOKEN = ""; // 这里填写自己的 token
       
       public static String APPID = ""; // 这里填写自己的 token APPID
       
        public static final String APPSECRET  = "";    
        
        public void bind() throws Exception {
            
            String result="";
            if( getRequest().getMethod().equals("GET")) {
                result= singGet();
            }
            if( getRequest().getMethod().equals("POST")) {
                result= singPost();
            }
            renderJson(result);
           
        }

public String singGet() {
            String sign=getPara("signature");
            String timestamp=getPara("timestamp");
            String nonce=getPara("nonce");
            String echostr=getPara("echostr");
            
            List<String> list = new ArrayList<String>();
            
            list.add(nonce);
            list.add(TOKEN);
            list.add(timestamp);
            
            Collections.sort(list);
            String hash = getHash(list.get(0)+list.get(1)+list.get(2), "SHA-1");
            if(sign.equals(hash)){ // 验证下签名是否正确
                return echostr;
            }else{
                return "";
            }
        }
        
        public String singPost() {
              HttpServletRequest request=getRequest();
              try {
                    
                    String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect ";
                    String redirectUrl="http://www.badqh.cn/jeeplus_union/WxUnion/index.html";
                    url=url.replace("APPID",APPID).replace("REDIRECT_URI", redirectUrl);
                    
                    String resAHref="<a href='"+url+"'>登录</a>";
                    System.out.println(resAHref);
                    Map<String,String> requestMap=parseRequest(request.getInputStream());
                    String responseXml="<xml><ToUserName><![CDATA["+requestMap.get("FromUserName")+"]]></ToUserName><FromUserName><![CDATA["+requestMap.get("ToUserName")+"]]></FromUserName><CreateTime>"+System.currentTimeMillis()/1000+"</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA["+resAHref+"]]></Content></xml>";
                    return responseXml;
                }catch (Exception e) {
                    e.printStackTrace();
                }
                return "";
        }

public  String getHash(String source, String hashType) {
            StringBuilder sb = new StringBuilder();
            MessageDigest md5;
            try {
                md5 = MessageDigest.getInstance(hashType);
                md5.update(source.getBytes());
                for (byte b : md5.digest()) {
                    sb.append(String.format("%02x", b));
                }
                return sb.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return null;
        }
        
        public static Map<String, String> parseRequest(InputStream in) throws DocumentException {
            Map<String,String> map=new HashMap<String, String>();
               SAXReader reader = new SAXReader();
                Document document = reader.read(in);
                Element root = document.getRootElement();
                Iterator it = root.elementIterator();
                while (it.hasNext()) {
                    Element element = (Element) it.next();
                    map.put(element.getName(), element.getStringValue());
                }
            return map;
        }
        
        //获取用户的openid
        public  void openid() throws Exception   {
               Map<String ,Object> resultMap = new HashMap<String ,Object>();
             
                String code=getPara("code");
               String reUrl=getPara("reUrl");
               
               String openid="";
            
                  if(StringUtils.isNotEmpty(code)){
                      String wxUrl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
                       wxUrl=wxUrl.replace("APPID",APPID).replace("SECRET", APPSECRET).replace("CODE", code);
                       HttpClientUtils   httpUtils =  new HttpClientUtils();
                        //解析成Json格式
                       JSONObject jsonObject=JSONObject.fromObject(httpUtils.doGet(wxUrl));
                       
                       openid = jsonObject.getString("openid");
                       resultMap.put("openid", openid);
                       
                       Redis.use("gc_wx").setex(openid+"_access_token", 7200,jsonObject.getString("access_token"));
                       Redis.use("gc_wx").setex(openid+"_refresh_token", 108000,jsonObject.getString("refresh_token"));
                       renderJson( new WxReurnMap(1,resultMap));   //操作码2001为跳转reUrl     
                    }else if(StringUtils.isNotEmpty(reUrl)){
                           resultMap.put("reUrl", "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect".replace("APPID",APPID).replace("REDIRECT_URI",URLEncoder.encode(reUrl,"utf8")));
                           renderJson( new WxReurnMap(1,resultMap,2001));   //操作码2001为跳转reUrl
                    }
                  
                  
        }
        
        //获取access_token的方法
        public  String getAccessToken(String openid) throws Exception   {
            
              String openid_access_token= Redis.use("gc_wx").get(openid+"_access_token");
              
              if(StringUtils.isNotEmpty(openid_access_token)) {
                  return  openid_access_token;
              }else {
                
                  String flushAccessTokenUrl="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
                  
                  String code=getPara("code");
                
                  Map<String ,Object> resultMap = new HashMap<String ,Object>();
                 
                  
                    String refresh_token=  Redis.use("gc_wx").get(openid+"_refresh_token");
                  
                    flushAccessTokenUrl=flushAccessTokenUrl.replace("APPID",APPID).replace("REFRESH_TOKEN", refresh_token);
                    
                      HttpClientUtils   httpUtils =  new HttpClientUtils();
                    //解析成Json格式
                   JSONObject jsonObject=JSONObject.fromObject(httpUtils.doGet(flushAccessTokenUrl));
                   openid_access_token=jsonObject.getString("access_token");
                   Redis.use("gc_wx").setex(openid+"_access_token", 7200,openid_access_token);
              }
            
              return openid_access_token;
        }
        
        //根据openid获取头像
        public  void getUserInfo() throws Exception    {

Map<String ,Object> resultMap = new HashMap<String ,Object>();
               
               String openid=getPara("openid");
               String access_token=getAccessToken(openid);
               
               String wxUrl=" https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN".replace("ACCESS_TOKEN",access_token).replace("OPENID",openid);
               
               HttpClientUtils   httpUtils =  new HttpClientUtils();
                //解析成Json格式
               JSONObject jsonObject=JSONObject.fromObject(httpUtils.doGet(wxUrl));
               resultMap.put("nickname", jsonObject.getString("nickname"));
               resultMap.put("language", jsonObject.getString("language"));
               resultMap.put("headimgurl", jsonObject.getString("headimgurl"));
               resultMap.put("province", jsonObject.getString("province"));
               resultMap.put("country", jsonObject.getString("country"));
               resultMap.put("headimgurl", jsonObject.getString("headimgurl"));
                 
                   renderJson( new WxReurnMap(1,resultMap));   
               }
        }

================================================================================================前端请求代码:

var wxdata = {
    redirect_uri: window.location.href,
    openid:"",    
    openid_url :function(){
           return "http://www.badqh.cn/kejin/wxController/openid";
    },
    // 获取openid
    get_openid : function(){
        //若openid未过期,返回缓存的openid
        if(localStorage.getItem("openid")!=""){
            return localStorage.getItem("openid");
        }

var code = $.getUrlParam('code');
        
        $.ajax({
            type : "GET",
            url : wxdata.openid_url(),
            data:{code:code,reUrl:wxdata.redirect_uri},
            async : false,
            success : function(rtnData) {
                //放到缓存
                console.log(rtnData);
                if(rtnData.optionCode==2001){
                  //跳转页面
                  window.location.href=rtnData.data.reUrl;                    
                 }else{
                     var opid=rtnData.data.openid;
                     localStorage.setItem("openid",opid);
                 }
            
            },
            error : function(msg){
                alert("get openid  error!!! ");
            }
        });
    }
    //其他
}

================================================================================================

get-url.js:

/*获取到Url里面的参数*/
(function($) {
    //只能是英文
    $.getUrlParam = function(key) {
        var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if(r != null) return unescape(r[2]);
        return null;
    }

//可以是中文,可以是英文
    $.getCNUrlParam = function(key) {
        // 获取参数
        var url = window.location.search;
        // 正则筛选地址栏
        var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
        // 匹配目标参数
        var result = url.substr(1).match(reg);
        //返回参数值
        return result ? decodeURIComponent(result[2]) : null;
    }
})(jQuery);

================================================================================================HttpClientUtils:

package cn.jbolt.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

public class HttpClientUtils {
    
       public String doPost(String url, String param) {
            PrintWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                URLConnection conn = realUrl.openConnection();
                // 设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                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()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("[POST请求]向地址:" + url + " 发送数据:" + param + " 发生错误!");
            } finally {// 使用finally块来关闭输出流、输入流
                try {
                    if (out != null) {
                        out.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException ex) {
                    System.out.println("关闭流异常");
                }
            }
            return result;
        }

public String doGet(String url) {
            String result = "";
            BufferedReader in = null;
            try {
                String urlName = url;
                URL realUrl = new URL(urlName);
                URLConnection conn = realUrl.openConnection();// 打开和URL之间的连接
                conn.setRequestProperty("accept", "*/*");// 设置通用的请求属性
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                conn.setConnectTimeout(4000);
                conn.connect();// 建立实际的连接
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));// 定义BufferedReader输入流来读取URL的响应
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("发送GET请求出现异常!" + e);
            } finally {// 使用finally块来关闭输入流
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException ex) {
                    System.out.println("关闭流异常");
                }
            }
            return result;
        }
        
}

微信公众号接入和获取用户信息相关推荐

  1. Spring boot 项目(十三)——实现微信公众号授权登录获取用户信息

    引言 微信公众号开发中,必不可少的一环:公众号授权登录.获取微信用户信息 前期准备 内网渗透=>生成本地指定端口映射的外网域名 链接:内网渗透工具natapp使用详解 域名生成之后修改yml文件 ...

  2. 微信公众号开发之获取用户信息

    微信获取用户信息的方式有两种,静默授权(无需用户同意)和非静默授权(需要用户" 手动点击 "拉取授权,可以用户无需关注公众号即可获取用户信息) 整体的代码请查看最后,前边为原理介绍 ...

  3. 微信公众号授权(获取用户信息)

    需要的工具: 微信公众号(可以申请,但做开发的,可以申请测试号,申请详细不多说了) 服务器(可以自行购买,我使用的是新浪的sae.) 编辑器(随意,不做推荐) 微信公众号开发文档(地址) !!!!!完 ...

  4. java实现微信公众号授权登录获取用户信息(一)

    参考文章:https://blog.csdn.net/Santiago_M/article/details/79109154 : https://www.cnblogs.com/jilu/p/6123 ...

  5. 基于Spring Boo微信公众号授权登录获取用户信息(附带完整源码)

    简介 微信公众号开发中,必不少可少的一环:公众号授权登录.获取微信用户信息. 本地完整运行环境准备 内网渗透=>生成本地指定端口映射的外网域名 传送门:内网渗透工具Natapp使用详解 域名生成 ...

  6. 【微信公众号开发】获取用户信息时,有时成功获取,有时提示“invalid openid hint”

    原因:保存openid的session在某个方法里被重新赋新值了.所以一旦调用了这个方法,再去获取用户信息时,就会报错.

  7. 微信公众号网页授权获取用户信息的流程

    官网文档 网页授权流程分为四步: 引导用户进入授权页面同意授权,获取code 通过 code 换取网页授权access_token(与基础支持中的access_token不同)(我的需求只需要到第二部 ...

  8. Spring Boot + 微信公众号授权登录获取用户信息

    通过微信公众平台的官方文档,总结出网页授权流程分为: 1.引导用户进入授权页面同意授权,获取code 2.通过code换取网页授权access_token(与基础支持中的access_token不同) ...

  9. 微信公众号,JS-SDK获取位置信息,并调起第三方地图App导航

    微信公众号关联网页获取位置信息,可以参照<微信公众平台技术文档>-> 微信JS-SDK说明文档,官方链接地址:https://mp.weixin.qq.com/wiki?t=reso ...

最新文章

  1. 【seaborn】(1) 数据可视化,绘图风格、布局
  2. 图解Detours实例
  3. OpenCV-图像的基本处理-02
  4. 3_8 StateMode 状态模式
  5. rocketmq怎么保证数据不会重复_阿里架构师亲授:Kafka和RocketMQ的消息复制实现的差异点在哪?...
  6. 微博热榜排行榜zset
  7. 循环体(for/while)循环变量的设置
  8. webvector将html转为svg或者png图片的工具
  9. fastjson jsonobject 转bean失败_挂面这么做,零失败,口感还是一顶一的棒
  10. 信息率失真函数matlab,基于MATLAB的信息率失真函数计算本科毕业论文.doc
  11. android联想搜索不到wifi,联想笔记本搜不到无线网解决办法
  12. CentOS 6.5 安装Redis并设置开机自启动
  13. 别有幽愁暗恨生,此时无声胜有声——python循环结构
  14. 读书笔记 - 机器学习实战 - 4 利用概率理论进行分类:朴素贝叶斯
  15. Greenplum小把戏 - 简单函数实现URL解码(URL Decode)- 同样适用于Deepgreen和PostgreSQL...
  16. liferay6.2 使用默认方式实现可配置的portlet
  17. 0基础快速开发口袋网盘小程序
  18. 2019,我的工作寻找之路
  19. 文件上传文件名乱码的解决方法及形成乱码原因
  20. java公寓管理系统设计与实现,学生公寓管理系统的设计与实现(MySQL)

热门文章

  1. 一条命令(dd)制作Centos(Linux)优盘(U盘)启动盘
  2. 淘宝主播榜单丨2月22日-2月28日淘宝直播榜单
  3. Attribute特性定义及应用
  4. 什么是https证书?
  5. 一般游戏原画制作的步骤是什么
  6. 'BMap' is not defined 解决方案,亲测有效
  7. 本题要求提取一个字符串中的所有数字字符(‘0‘……‘9‘),将其转换为一个整数输出。
  8. 将图形中线条或者图案坐标点进行提取
  9. 健身中心管理_操作简单
  10. python听不懂_看日本电影真痛苦,本来就听不懂!还没字幕!6行代码音频转文字...