微信公众号接入和获取用户信息
主要原理:
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;
}
}
微信公众号接入和获取用户信息相关推荐
- Spring boot 项目(十三)——实现微信公众号授权登录获取用户信息
引言 微信公众号开发中,必不可少的一环:公众号授权登录.获取微信用户信息 前期准备 内网渗透=>生成本地指定端口映射的外网域名 链接:内网渗透工具natapp使用详解 域名生成之后修改yml文件 ...
- 微信公众号开发之获取用户信息
微信获取用户信息的方式有两种,静默授权(无需用户同意)和非静默授权(需要用户" 手动点击 "拉取授权,可以用户无需关注公众号即可获取用户信息) 整体的代码请查看最后,前边为原理介绍 ...
- 微信公众号授权(获取用户信息)
需要的工具: 微信公众号(可以申请,但做开发的,可以申请测试号,申请详细不多说了) 服务器(可以自行购买,我使用的是新浪的sae.) 编辑器(随意,不做推荐) 微信公众号开发文档(地址) !!!!!完 ...
- java实现微信公众号授权登录获取用户信息(一)
参考文章:https://blog.csdn.net/Santiago_M/article/details/79109154 : https://www.cnblogs.com/jilu/p/6123 ...
- 基于Spring Boo微信公众号授权登录获取用户信息(附带完整源码)
简介 微信公众号开发中,必不少可少的一环:公众号授权登录.获取微信用户信息. 本地完整运行环境准备 内网渗透=>生成本地指定端口映射的外网域名 传送门:内网渗透工具Natapp使用详解 域名生成 ...
- 【微信公众号开发】获取用户信息时,有时成功获取,有时提示“invalid openid hint”
原因:保存openid的session在某个方法里被重新赋新值了.所以一旦调用了这个方法,再去获取用户信息时,就会报错.
- 微信公众号网页授权获取用户信息的流程
官网文档 网页授权流程分为四步: 引导用户进入授权页面同意授权,获取code 通过 code 换取网页授权access_token(与基础支持中的access_token不同)(我的需求只需要到第二部 ...
- Spring Boot + 微信公众号授权登录获取用户信息
通过微信公众平台的官方文档,总结出网页授权流程分为: 1.引导用户进入授权页面同意授权,获取code 2.通过code换取网页授权access_token(与基础支持中的access_token不同) ...
- 微信公众号,JS-SDK获取位置信息,并调起第三方地图App导航
微信公众号关联网页获取位置信息,可以参照<微信公众平台技术文档>-> 微信JS-SDK说明文档,官方链接地址:https://mp.weixin.qq.com/wiki?t=reso ...
最新文章
- 【seaborn】(1) 数据可视化,绘图风格、布局
- 图解Detours实例
- OpenCV-图像的基本处理-02
- 3_8 StateMode 状态模式
- rocketmq怎么保证数据不会重复_阿里架构师亲授:Kafka和RocketMQ的消息复制实现的差异点在哪?...
- 微博热榜排行榜zset
- 循环体(for/while)循环变量的设置
- webvector将html转为svg或者png图片的工具
- fastjson jsonobject 转bean失败_挂面这么做,零失败,口感还是一顶一的棒
- 信息率失真函数matlab,基于MATLAB的信息率失真函数计算本科毕业论文.doc
- android联想搜索不到wifi,联想笔记本搜不到无线网解决办法
- CentOS 6.5 安装Redis并设置开机自启动
- 别有幽愁暗恨生,此时无声胜有声——python循环结构
- 读书笔记 - 机器学习实战 - 4 利用概率理论进行分类:朴素贝叶斯
- Greenplum小把戏 - 简单函数实现URL解码(URL Decode)- 同样适用于Deepgreen和PostgreSQL...
- liferay6.2 使用默认方式实现可配置的portlet
- 0基础快速开发口袋网盘小程序
- 2019,我的工作寻找之路
- 文件上传文件名乱码的解决方法及形成乱码原因
- java公寓管理系统设计与实现,学生公寓管理系统的设计与实现(MySQL)
热门文章
- 一条命令(dd)制作Centos(Linux)优盘(U盘)启动盘
- 淘宝主播榜单丨2月22日-2月28日淘宝直播榜单
- Attribute特性定义及应用
- 什么是https证书?
- 一般游戏原画制作的步骤是什么
- 'BMap' is not defined 解决方案,亲测有效
- 本题要求提取一个字符串中的所有数字字符(‘0‘……‘9‘),将其转换为一个整数输出。
- 将图形中线条或者图案坐标点进行提取
- 健身中心管理_操作简单
- python听不懂_看日本电影真痛苦,本来就听不懂!还没字幕!6行代码音频转文字...