2016-02-24 20:34:01 kingmax54212008 阅读数 7199
  • 微信公众号开发7-用户管理-微信开发php

    微信公众平台开发之微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131

    13974 人正在学习 去看看 秦子恒

本文介绍如何获得微信公众平台关注用户的基本信息,包括昵称、头像、性别、国家、省份、城市、语言。
本文的方法将囊括订阅号和服务号以及自定义菜单各种场景,无论是否有高级接口权限,都有办法来获得用户基本信息,而无需模拟登录。

 

在本文中,特别要注意的是有两个不同的Access Token,他们产生的方式不一样,一种是使用AppID和AppSecret获取的access_token,一种是OAuth2.0授权中产生的access_token,方倍工作室分别称为全局Access Token授权Access Token。

 

一、通过全局Access Token获取用户基本信息

1. 用户关注以及回复消息的时候,均可以获得用户的OpenID

复制代码
<xml>
    <ToUserName><![CDATA[gh_b629c48b653e]]></ToUserName>
    <FromUserName><![CDATA[ollB4jv7LA3tydjviJp5V9qTU_kA]]></FromUserName>
    <CreateTime>1372307736</CreateTime>
    <MsgType><![CDATA[event]]></MsgType>
    <Event><![CDATA[subscribe]]></Event>
    <EventKey><![CDATA[]]></EventKey>
</xml>
复制代码

其中的FromUserName就是OpenID

2. 然后使用access_token接口,请求获得全局Access Token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

返回结果:

{
    "access_token": "NU7Kr6v9L9TQaqm5NE3OTPctTZx797Wxw4Snd2WL2HHBqLCiXlDVOw2l-Se0I-WmOLLniAYLAwzhbYhXNjbLc_KAA092cxkmpj5FpuqNO0IL7bB0Exz5s5qC9Umypy-rz2y441W9qgfnmNtIZWSjSQ",
    "expires_in": 7200
}

3. 再使用全局ACCESS_TOKEN获取OpenID的详细信息

https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID

返回如下:

复制代码
{
    "subscribe": 1,
    "openid": "oLVPpjqs2BhvzwPj5A-vTYAX4GLc",
    "nickname": "刺猬宝宝",
    "sex": 1,
    "language": "zh_CN",
    "city": "深圳",
    "province": "广东",
    "country": "中国",
    "headimgurl": "http://wx.qlogo.cn/mmopen/JcDicrZBlREhnNXZRudod9PmibRkIs5K2f1tUQ7lFjC63pYHaXGxNDgMzjGDEuvzYZbFOqtUXaxSdoZG6iane5ko9H30krIbzGv/0",
    "subscribe_time": 1386160805
}
复制代码

至此,获得用户的基本信息。

2016-10-27 16:45:22 xiaoyezihanghui 阅读数 5046
  • 微信公众号开发7-用户管理-微信开发php

    微信公众平台开发之微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131

    13974 人正在学习 去看看 秦子恒


释: 我是订阅号,申请的微信开发测试账号,操作授权登录


1.  下载web开发工具


2.  在公众号列表中, 开发者工具-》web开发工具-> 绑定开发者账号 -》输入你的微信号(微信号需关注公众号才可绑定),邀请绑定在微信客户端确认邀请即可


3.  在测试管理账号中, 网页授权获取用户基本信息  接口,点击修改  填充(授权回调页面域名),沙盒测试环境不限ip和域名,我填充的ip ( 注释: ip填充只需 如192.168.0.1:port,前缀不需要http,此坑已踩)


4.  授权链接 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx58caa75dbeb054aa&redirect_uri=http://192.168.0.1:8014/wechat_login&response_type=code&scope=snsapi_userinfo&state=1   回调按照自己的需求更改即可

2018-07-09 15:26:38 qq_42547698 阅读数 17863
  • 微信公众号开发7-用户管理-微信开发php

    微信公众平台开发之微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131

    13974 人正在学习 去看看 秦子恒

配置微信公众号开发环境就不赘述了。

进入正题。。。。。

首先,先理清楚微信登录的两种实现途径(这里我们先演示一种)1.微信开放平台实现,2.微信公众号(微信公众平台)实现。

因为微信登录不同与QQ登录,微信登录只提供扫码方式登录,并不像其他应用登录让用户输入用户名,密码。对用户并不友好。所以出现微信公众号登录,让用户授权。

实现方式也是两种:

1.没有自己的帐号体系,直接拉去微信用户信息来进行网站登录(我们所展示的信息全部来自于微信)

2.有自己的账号体系,授权成功后需要绑定自己的账号,绑定成功后,下次登录所展示的信息是自己的账号体系下面的用户信息

下面开始

1.微信公众号,推荐使用测试账号(拥有所有权限)

2.看微信授权登录的文档

3.代码部分了(尽可能的加上了注释)

工具类

package com.wlw.util;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import net.sf.json.JSONObject;

/**
 * 
 * 工具类
 * 用来根据接口地址进行网络请求
 * @author wlw
 *
 */
public class AuthUtil {
	public static final String APP_ID = "****************";     //填写自己的APPID
	public static final String APP_SECRET = "**************";   //填写自己的APPSECRET
    public static JSONObject doGetJson(String url) throws Exception, IOException {
		JSONObject jsonObject=null;
		//初始化httpClient
		DefaultHttpClient client=new DefaultHttpClient();
		//用Get方式进行提交
		HttpGet httpGet=new HttpGet(url);
		//发送请求
		HttpResponse response= client.execute(httpGet);
    	//获取数据
		HttpEntity entity=response.getEntity();
		//格式转换
		if (entity!=null) {
			String result=EntityUtils.toString(entity,"UTF-8");
			jsonObject=JSONObject.fromObject(result);
		}
		//释放链接
		httpGet.releaseConnection();
		return jsonObject;
    }
	   
}

组装入口地址

package com.wlw.servlet;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wlw.util.AuthUtil;;

/**
 * 组装入口地址
 * 进行授权页面的授权地址组装
 * @author wlw
 *
 */
@WebServlet("/wxLogin")
public class LoginServiet extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//回调地址(必须在公网进行访问)
		String backUrl="http://w.ngrok.xiaomiqiu.cn/we/callBack";
		String url="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+AuthUtil.APP_ID
				+ "&redirect_uri="+URLEncoder.encode(backUrl)
				+ "&response_type=code"
				+ "&scope=snsapi_userinfo"
				+ "&state=STATE#wechat_redirect";
		//重定向
		resp.sendRedirect(url);
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}
}

到这里很多人不明白回调地址到底是个啥玩意,

回调地址是当我们用户同意授权后,程序会进行对回调地址的访问。所以回调地址必须在公网上能够进行访问的。

还有个重点是scope(授权的作用域)。两个参数snsapi_base、snsapi_userinfo。。使用base作用域,不会弹出会话框,直接跳过,直接进入到回调地址,运行之后的程序,它默认是授权的(只能获取到openid)。。而userinfo,会弹出会话框,让用户选择,确认,才会进入回调地址(获取openID,通过openID拿到其他信息),用户取消则不进入回调地址。

微信公众号的bug之一就出现了,如果先使用userinfo作用域,再去使用base作用域,居然也能获取到用户的其他信息。至于为什么就要去问微信的开发大佬了。

回调地址的处理

package com.wlw.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wlw.util.AuthUtil;
import net.sf.json.JSONObject;

/**
 * 回调地址
 * 
 * @author wlw
 *
 */
@WebServlet("/callBack")
public class CallBackServlet extends HttpServlet {
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		/**
		 * 3.获取code
		 */
		String code=req.getParameter("code");
	String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="+AuthUtil.APP_ID
			+ "&secret="+AuthUtil.APP_SECRET
			+ "&code="+code
			+ "&grant_type=authorization_code";
	JSONObject jsonObject;
	try {
		jsonObject = AuthUtil.doGetJson(url);
		String openid=jsonObject.getString("openid");
		String token=jsonObject.getString("access_token");
		/**
		 * 4.拉取用户信息
		 */
		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);
		
		//使用微信用户信息直接登录,无需注册和绑定
		req.setAttribute("info", userInfo);
		req.getRequestDispatcher("/index1.jsp").forward(req, resp);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}

}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body style="font-size:40px;text-align:center;">
    <a href="/we/wxLogin">微信公众 版权登录</a>
</body>
</html>

index1.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body style="font-size:40px;text-align:center;">
   <div>登录成功!</div>
   <div>用户昵称: ${info.nickname}</div>
   <div>用户头像: <img style="vertical-align: top;" width="100" height="" alt="" src="${info.headimgurl}"></div>
   <div>登录成功!</div>
</body>
</html>

 

 

 

截图配置信息

写自己的域名。。。不要带http

参考图2 截图配置信息  这里应该填   1afa5dc0.ngrok.io

然后在浏览器输入地址访问,会显示需要在微信端进行访问.

只需将地址换成二维码,扫描即可。如何换成二维码呢,我建议使用谷歌浏览器,方便,直接在地址栏右击,就会有二维码。扫一扫即可。

微信扫描,点击授权,登录进去页面显示

后台获取到的数据

原理就是两个Servlet和两个JSP页面。一个是用户进入的登录页面,只不过不用输入用户名密码,直接授权登录。另外一个页面为展示用户的数据。两个Servlet配合JSP页面处理后台。

这一次演示的是没有自己帐号体系,不需要绑定,直接登录。

帐号体系的授权登录自行百度。

2017-04-15 11:58:23 liaohaojian 阅读数 20980
  • 微信公众号开发7-用户管理-微信开发php

    微信公众平台开发之微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131

    13974 人正在学习 去看看 秦子恒

从接触公众号到现在,通过不断积累学习,对如何调用微信提供接口有了一定的见解。当然在开发过程中遇到很多问题,现在把部分模块功能在这备案一下,做个总结也希望能给其他人帮助

工欲善其事,必先利其器,先看看开发公众号需要准备或了解什么

  1. web开发工具:官方提供的开发工具,使用自己的微信号来调试微信网页授权、调试、检验页面的 JS-SDK 相关功能与权限,模拟大部分 SDK 的输入和输出。下载地址:web开发工具下载
  2. 开发文档:https://mp.weixin.qq.com/wiki
  3. 登录微信测试公众号,获取公众号的appID、appsecret,登录地址:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login (一般测试开发阶段,都不拿正式公众号测试,因为存在风险并且你调试时不用担心影响到正式公众号的正常使用,而且有些接口在正式公众号上比较严格,而在测试公众号上可以放开,如模板信息)

下面进入正题,实现微信网页授权,获取微信信息,主要用于以微信帐号作为用户登录,如果你只是需要绑定微信,就可以不用授权,直接请求获取微信OpenId(对当前公众号唯一),进行用户绑定(在下面代码时是写明如何实现),该功能可在开发文档:微信网页开发-》微信网页授权里查看详细信息,下面正式开始。

1.填写授权回调页面域名

进入测试公众号,在体验接口权限表中找到网页帐号,右侧添加自己的域名,测试公众号可填写本地IP,如你是正式公众号只能填写自己的域名,如果未填写,当进行接口调用时,会提示:redirect_uri参数错误!如果还有其他不了解的配置,可以在开发文档里查看详信息,

2.代码展示

1).调用微信接口返回的参数都是JSON格式,封装个Http请求方法
public class WeixinUtil {
       /**
	 * 发起https请求并获取结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式(GET、POST)
	 * @param outputStr 提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
   public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
	JSONObject jsonObject = null;
	StringBuffer buffer = new StringBuffer();
	try {
		// 创建SSLContext对象,并使用我们指定的信任管理器初始化
		TrustManager[] tm = { new MyX509TrustManager() };
		SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
		sslContext.init(null, tm, new java.security.SecureRandom());
		// 从上述SSLContext对象中得到SSLSocketFactory对象
		SSLSocketFactory ssf = sslContext.getSocketFactory();
		URL url = new URL(requestUrl);
		HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
		httpUrlConn.setSSLSocketFactory(ssf);
		httpUrlConn.setDoOutput(true);
		httpUrlConn.setDoInput(true);
		httpUrlConn.setUseCaches(false);
		// 设置请求方式(GET/POST)
		httpUrlConn.setRequestMethod(requestMethod);
		if ("GET".equalsIgnoreCase(requestMethod))
			httpUrlConn.connect();
		// 当有数据需要提交时
		if (null != outputStr) {
			OutputStream outputStream = httpUrlConn.getOutputStream();
			// 注意编码格式,防止中文乱码
			outputStream.write(outputStr.getBytes("UTF-8"));
			outputStream.close();
		}
		// 将返回的输入流转换成字符串
		InputStream inputStream = httpUrlConn.getInputStream();
		InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
		String str = null;
		while ((str = bufferedReader.readLine()) != null) {
			buffer.append(str);
		}
		bufferedReader.close();
		inputStreamReader.close();
		// 释放资源
		inputStream.close();
		inputStream = null;
		httpUrlConn.disconnect();
		jsonObject = JSONObject.fromObject(buffer.toString());
	} catch (ConnectException ce) {
		log.error("Weixin server connection timed out.");
	} catch (Exception e) {
		log.error("https request error:{}", e);
	}
	return jsonObject;
    }
}
2).下面展示访问个人中心时,进行用户授权
/**
 * 个人中心
 * @param request
 * @param response
 * @return
 */
@RequestMapping("/gotoPeopleIndex")
public String gotoPeopleIndex(HttpServletRequest request,HttpServletResponse response){
	//判断是否授权过,授权通过时,会保存session“WeixinUserInfo”,这样下次访问时,如果WeixinUserInfo存在,说明已经授权过,用户信息已经存在
	WeixinUserInfo WeixinUserInfo =  (WeixinUserInfo) session.getAttribute("WeixinUserInfo");
	if(WeixinUserInfo==null){//没有授权过,跳转授权页面,如果你不需要授权,则scope为snsapi_base,这是不会弹出授权页面
		String url  = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+TimedTask.appid+"&redirect_uri="+TimedTask.websiteAndProject+"/weixinF/getOpenInfo/gotoPeopleIndex&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
		return "redirect:"+url;
	}else{
		return "weixin/customer/userInfo";
	}
}
/**
 * 微信网页授权获得微信详情
 * @param code
 * @param state
 * @param view 授权后调整的视图
 * @param request
 * @param appid 公众号appid
 * @param appsecret 公众号appsecret
 * @param websiteAndProject  请求地址跟工程名,如我当前的为http://192.168.2.113/seafood
 * @param response
 * @throws ServletException
 * @throws IOException
 */
@RequestMapping("/getOpenInfo/{view}")
public void getOpenInfo(@RequestParam("code") String code,@RequestParam("state") String state,@PathVariable("view") String view,HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{
	// 用户同意授权
	if (!"authdeny".equals(code)) {
		//获取OpenId
		OpenIdResult open = WeixinUtil.getOpenId(request, code, TimedTask.appid, TimedTask.appsecret);
		//检验授权凭证(access_token)是否有效
		int result = WeixinUtil.checkAccessToken(open.getAccess_token(), open.getOpenid());
		if(0 != result){
			open = WeixinUtil.getNewAccess_Token(open,open.getRefresh_token(),TimedTask.appid);
		}
		// 网页授权接口访问凭证
		String accessToken = open.getAccess_token();
		String openId = open.getOpenid();
		//获取微信用户详细信息,如果你不需要授权,可跳过该步骤,直接以微信的OpenId,查找是否已经绑定,没有跳转到绑定界面
		WeixinUserInfo user = WeixinUtil.getWeixinUserInfo(accessToken, openId);
		Customer customer = weixinFirstServer.getCustomerDetailByOpenId(user.getOpenId());
		if(customer!=null){
			if(customer.getAccountStatus()==2){
				response.setContentType("text/html; charset=UTF-8");
				try {
					response.sendRedirect(TimedTask.websiteAndProject+"/weixin/customer/noAuthority.jsp");
				} catch (IOException e) {
					e.printStackTrace();
				}
				return;
			}
			customer.setHeadPhoto(user.getHeadImgUrl());
		}else{
			Customer newuser = new Customer();
			newuser.setCustomerWeixinId(openId);
			newuser.setCustomerWNickname(user.getNickname());
			newuser.setSex(user.getSex());
			//绑定
			result = weixinFirstServer.addCustomerInfo(newuser);
			if(result<=0){
				response.setContentType("text/html; charset=UTF-8");
				try {
					response.sendRedirect(TimedTask.websiteAndProject+"/weixin/customer/error.jsp");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}else{
				customer = weixinFirstServer.getCustomerDetailByOpenId(user.getOpenId());
				if(customer.getAccountStatus()==2){
					response.setContentType("text/html; charset=UTF-8");
					try {
						response.sendRedirect(TimedTask.websiteAndProject+"/weixin/customer/noAuthority.jsp");
					} catch (IOException e) {
						e.printStackTrace();
					}
					return;
				}
			}
		}
		session.setAttribute("customerInfo", customer);
		session.setAttribute("WeixinUserInfo", user);
		request.setAttribute("state", state);
		response.setContentType("text/html; charset=UTF-8");
		try {
			response.sendRedirect(TimedTask.websiteAndProject+"/weixinF/"+view);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}else{
		response.setContentType("text/html; charset=UTF-8");
		try {
			response.sendRedirect(TimedTask.websiteAndProject+"/weixin/customer/error.jsp");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
微信工具类代码:
public class WeixinUtil {
	public final static String getOpen_id_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	public final static String getNewAccess_token = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
/**
	 * 检验授权凭证(access_token)是否有效
	 * @param accessToken 凭证
	 * @param openid id
	 * @return
	 */
	public static int checkAccessToken(String accessToken, String openid) {
		String requestUrl = "https://api.weixin.qq.com/sns/auth?access_token="+accessToken+"&openid="+openid;
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		int result = 1;
		// 如果请求成功
		if (null != jsonObject) {
			try {
				result = jsonObject.getInt("errcode");
			} catch (JSONException e) {
				accessToken = null;
				// 获取token失败
				log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
			}
		}
		return result;
	}
	/**
	 * 用户授权,使用refresh_token刷新access_token
	 * @return
	 */
	public static OpenIdResult getNewAccess_Token(OpenIdResult open,String refresh_token,String openId) {
		String requestUrl = getNewAccess_token.replace("REFRESH_TOKEN", refresh_token).replace("APPID", openId);
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		// 如果请求成功
		if (null != jsonObject) {
			try {
				open.setAccess_token(jsonObject.getString("access_token"));
			} catch (JSONException e) {
				// 获取token失败
				log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
			}
		}
		return open;
	}
	/**
	 * 获得用户基本信息
	 * @param request 
	 * @param code
	 * @param appid
	 * @param appsecret
	 * @return
	 */
	public static OpenIdResult getOpenId(HttpServletRequest request, String code,String appid, String appsecret) {
		String requestURI = request.getRequestURI();
		String param = request.getQueryString();
		if(param!=null){
			requestURI = requestURI+"?"+param;
		}
		String url = getOpen_id_url.replace("APPID",appid).replace("SECRET",appsecret).replace("CODE",code);
		JSONObject jsonObject = httpRequest(url, "POST", null);
		OpenIdResult result = new OpenIdResult();
		if (null != jsonObject) {
			Object obj = jsonObject.get("errcode");
			if (obj == null) {
				result.setAccess_token(jsonObject.getString("access_token"));
				result.setExpires_in(jsonObject.getString("expires_in"));
				result.setOpenid(jsonObject.getString("openid"));
				result.setRefresh_token(jsonObject.getString("refresh_token"));
				result.setScope(jsonObject.getString("scope"));
			}else{
				System.out.println("获取openId回执:"+jsonObject.toString()+"访问路径:"+requestURI);
				log.error("访问路径:"+requestURI);
				log.error("获取openId失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
			}
		}
		return result;
	}
	/**
	 * 通过网页授权获取用户信息
	 * @param accessToken 网页授权接口调用凭证
	 * @param openId 用户标识
	 * @return WeixinUserInfo
	 */
	public static WeixinUserInfo getWeixinUserInfo(String accessToken, String openId) {
		WeixinUserInfo user = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
		// 通过网页授权获取用户信息
		JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				user = new WeixinUserInfo();
				// 用户的标识
				user.setOpenId(jsonObject.getString("openid"));
				// 昵称
				user.setNickname(jsonObject.getString("nickname"));
				// 性别(1是男性,2是女性,0是未知)
				user.setSex(jsonObject.getInt("sex"));
				// 用户所在国家
				user.setCountry(jsonObject.getString("country"));
				// 用户所在省份
				user.setProvince(jsonObject.getString("province"));
				// 用户所在城市
				user.setCity(jsonObject.getString("city"));
				// 用户头像
				user.setHeadImgUrl(jsonObject.getString("headimgurl"));
				// 用户特权信息
				user.setPrivilegeList(JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class));
			} catch (Exception e) {
				user = null;
				int errorCode = jsonObject.getInt("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取用户信息失败 errcode:{} errmsg:{},reqUrl{}", errorCode, errorMsg);
			}
		}
		return user;
	}
}
下面展示,当用户session失效时,自动登录的代码,这时是不需要授权的
@RequestMapping("/gotoGoodsView")
public String gotoGoodsView(@RequestParam(value="longitude",defaultValue="",required=false) String longitude,@RequestParam(value="latitude",defaultValue="",required=false) String latitude){
	String param = request.getQueryString();
	String url = request.getServletPath();
	if(param!=null){
		url = url+"?"+param.replaceAll("&","-");//如果不把&替换成别的,当重新登录成功后调整会参数丢失
	}
	Customer customerInfo = (Customer) session.getAttribute("customerInfo");
	if(customerInfo==null){//session失效,跳转到获取微信详情页面(授权)
		return "redirect:/weixinF/getCode?view="+TimedTask.websiteAndProject+"/weixinF/autoLogin&view2="+TimedTask.websiteAndProject+url;
	}
	return "/weixin/customer/goodsList";
}
@RequestMapping("/getCode")
public void getCode(HttpServletResponse response){
	String view  = request.getParameter("view");//获取openId的路径
	String view2  = request.getParameter("view2");//获取openId成功后跳转的路径
	String redirect_url = "";
	try {
		redirect_url = URLEncoder.encode(view,"UTF-8");
		if(view2!=null && !"".equals(view2)){
			view2 = view2.replaceAll("-","&");
			redirect_url = redirect_url +"?redirect_url="+ URLEncoder.encode(URLEncoder.encode(view2,"UTF-8"),"UTF-8");
		}
	} catch (UnsupportedEncodingException e1) {
		e1.printStackTrace();
	}
	String url = WeixinUtil.getCode_url.replace("APPID",TimedTask.appid).replace("REDIRECT_URI",redirect_url);
	response.setContentType("text/html; charset=UTF-8");
	try {
		response.sendRedirect(url);
	} catch (IOException e) {
		e.printStackTrace();
	}
}
/**
 * 自动登录并跳转
 * @param code
 * @param appid 公众号appid
 * @param appsecret 公众号appsecret
 * @param websiteAndProject  请求地址跟工程名,如我当前的为http://192.168.2.113/seafood
 * @param url 自动登录后跳转路径
 * @return
 */
@RequestMapping("/autoLogin")
public String autoLogin(HttpServletResponse response,@RequestParam(value="code",defaultValue="") String code,@RequestParam(value="redirect_url",defaultValue="") String url){
	OpenIdResult open = WeixinUtil.getOpenId(request,code,TimedTask.appid,TimedTask.appsecret);//根据Code获取OpenId
	//根据OpenId查找是否有该客户,没有进行绑定
	Customer customerInfo = weixinFirstServer.getCustomerDetailByOpenId(open.getOpenid());
	if(customerInfo!=null){
		if(customerInfo.getAccountStatus()==2){//用户账户是否正常
			return "redirect:"+TimedTask.websiteAndProject+"/weixin/customer/noAuthority.jsp";
		}
		session.setAttribute("customerInfo", customerInfo);//把用户信息存在session中
		response.setContentType("text/html; charset=UTF-8");
		try {
			response.sendRedirect(url);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}else{
		url= url.replaceAll("&","-");
		url = url.replace(TimedTask.websiteAndProject,"");
		String redirectUrl  = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+TimedTask.appid+"&redirect_uri="+TimedTask.websiteAndProject+"/weixinF/getOpenInfoRedirectAction?actionName="+url+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
		response.setContentType("text/html; charset=UTF-8");
		try {
			response.sendRedirect(redirectUrl);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
到此,微信网页授权认证,与session失效自动登录已经完成,如果有问题欢迎在评论区指出

2018-03-20 21:30:28 qq_33858250 阅读数 6247
  • 微信公众号开发7-用户管理-微信开发php

    微信公众平台开发之微信用户开发管理是子恒老师《微信公众平台开发》视频教程的第7部。详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131

    13974 人正在学习 去看看 秦子恒

开发须知

1.概念区分

  • 因为接触到微信开发的知识,必然会接触 OpenID 与 UnionID 的使用,以下为微信官方文档的的介绍,请注意区分:
  • 在关注者与公众号产生消息交互后,公众号可获得关注者的 OpenID(加密后的微信号,每个用户对每个公众号的 OpenID 是唯一的。对于不同公众号,同一用户的 OpenID 不同)。
  • 公众号可通过相应接口来根据 OpenID 获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
  • 请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用 UnionID 机制来满足上述需求。
  • 简单概括来讲:
  • OpenID 是普通用户的标识,对当前开发者帐号唯一。一个 OpenID 对应一个公众号。
  • UnionID 是用户统一标识。针对一个 微信开放平台帐号 下的应用,同一用户的 UnionID 是唯一的。

2.归纳整理

  • 绕了这个圈,也就是说,微信公众号开发与微信开发平台开发是有差别的
  • 想让同一个微信用户使用不同平台(如PC端、app、微信小程序等)的网站登录,需要进行账号绑定,而这个绑定的账号不能以 OpenID 区分,而需要用 UnionID 区分。

3.典型问题

  • 附录一个常见的设计问题,主要在于开发前的知识使用不够全面,而造成后续拓展的影响,当然,这也是我遇到的问题,希望可以给各位敲个警钟。
    典型问题

4、微信链接


申请接口流程

1、 微信公众号接口申请

  • 注册首先要去微信公众平台去注册帐号 微信公众平台

    • 具体注册帐号,请参考网上教程
    • 必须要求是必须是企业用户
    • 这一篇是我自己申请的订阅号,可以参考下申请流程开通个人微信公众号
  • 绑定运营者微信号当客户注册完之后,把他的帐号密码拿过来,自己进去先绑定一个自己的微信号(这样以便以后直接用自己的帐号就能进行登录。一个微信帐号只能绑定5个微信公众号管理员)

    • 设置->安全中心->管理员和运营者设置->绑定运营者微信号
      绑定运营者微信号
  • 基本配置把微信公众号的基本信息拿过来。最主要的还是把appid和appsecret给设置好

    • 开发->基本配置->公众号开发信息
      基本配置
  • 公众号设置接着设置微信公众号和自己网站对接

    • 公众号设置->功能设置->业务域名js接口安全域名网页授权域名
      公众号设置
  • 接口调试工具调试接口程序的方法

    • 开发->开发者中心->开发者文档在线接口调试工具web开发者工具
      接口调试工具
以上是申请操作
申请成功后获得微信公众号测试key
Appid:123456
AppSecret:000000000

2、 微信电脑接口申请

接口申请,必须要先微信公众平台注册申请,然后在去公众开放平台注册申请。
具体可以参考第一步操作。和第三步操作

以上是申请操作
申请成功后获得微信电脑登录测试key:
Apppid:456789
Appsecret:1000000000

3、 同时申请两个端,可进行绑定 关联

如果只是需要微信公众号端登录的话,可以不用设置的很麻烦。如果需要两种方式登录的话,就需要去微信开放平台进行绑定

  • 首先要去微信开放平台去注册帐号https://open.weixin.qq.com/

  • 如果需要在微信开放平台上面操作,请先在微信公众平台上申请一个帐号(参考:1、 微信公众号接口申请

  • 先进行帐号绑定

    • 帐号中心->基本资料开发者资质
      帐号绑定
  • 在进行接口绑定申请,当然这个申请完之后,以后的微信登录他都会返回一个特定的微信单独帐号的一个码(简称uid)

    • 微信公众号:管理中心->公众帐号
    • 微信电脑登录:网站应用->创建网站应用(创建完之后要设置授权回调域:www.xxx.com
      接口绑定
  • 绑定成功之后,获取他的APPIDAPPSECRET,每次登录都是需要获取这个不一样的id
    获取他的APPID和APPSECRET


以上就是申请流程。
下面可就操作,如何用php程序和他对接
上面的配置一定要配置好
公众号设置:
业务域名:www.meetes.top
JS接口安全域名:www.meetes.top
网页授权域名:www.meetes.top

微信公众号登录:
Appid:123456
AppSecret:000000000

微信电脑扫码登录:
Appid:456789
AppSecret:100000000


程序业务流程

我CSDN里有几篇是关于这个的,想了解更多的,可以去我的CSDN里看看

微信网页授权登录

大概思路流程是这样的:通过程序链接->从微信那边授权->获取微信那边返回的用户信息->然后进行组装->组装好插入到我们的数据库当中就行了

  • 通过OAuth2.0方式弹出授权页面获得用户基本信息(什么是OAuth2.0?

    • 简要概述什么是OAuth2.0:

    • OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的私密的资源(如用户个人信息、照片、视频、联系人列表),而无需将用户名和密码提供给第三方应用。

    • OAuth 2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。
    • OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
  • 获得微信公众平台关注用户的基本信息,包括昵称、头像、性别、国家、省份、城市、语言。

第一步:用户同意授权,获取code

  • 在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认带有scope参数中的snsapi_base和snsapi_userinfo),

  • 引导关注者打开如下页面:

1
2
https://open.weixin.qq.com/connect/oauth2/authorize?appid= `APPID` &redirect_uri= `REDIRECT_URI` &response_type=code&scope=SCOPE&state=STATE#wechat_redirect 
(若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。)
  • 参数说明:
    参数说明
  • 用户同意授权后
    • 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
    • code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
  • 将该链接回复给关注用户,用户点击后,弹出应用授权界面
    授权界面

第二步:通过code换取网页授权access_token

  • 首先请注意,这里通过code换取的网页授权access_token,与基础支持中的access_token不同。公众号可通过下述接口来获取网页授权access_token。

  • 如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

  • 获取code后,请求以下链接获取,请求方法:GET

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
access_token:  https://api.weixin.qq.com/sns/oauth2/access_token?appid= `APPID` &secret=SECRET&code= `CODE` &grant_type=authorization_code

``` 

* 参数说明
  ![参数说明](/images/categories/wechat/2018/03/0320_04.png)

* 返回说明

```JS
正确时返回的JSON数据包如下:
{

  "access_token":"ACCESS_TOKEN",

   "expires_in":7200,

  "refresh_token":"REFRESH_TOKEN",

   "openid":"OPENID",

   "scope":"SCOPE"

}
  • 返回参数说明
    返回参数说明

  • 错误时微信会返回JSON数据包如下(示例为Code无效错误):

    • {“errcode”:40029,”errmsg”:”invalid code”}

第三步:刷新access_token(如果需要)(一般是不会用到这一步的)(忽略)

  • 由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。

  • 请求方法:GET

  • 获取第二步的refresh_token后,请求以下链接获取access_token:

1
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid= `APPID` &grant_type=refresh_token&refresh_token= `REFRESH_TOKEN`
  • 参数说明:
    参数说明

  • 返回说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
正确时返回的JSON数据包如下:
{

  "access_token":"ACCESS_TOKEN",

   "expires_in":7200,

  "refresh_token":"REFRESH_TOKEN",

   "openid":"OPENID",

   "scope":"SCOPE"

}
  • 返回参数说明
    返回参数说明

  • 错误时微信会返回JSON数据包如下(示例为Code无效错误):

    • {“errcode”:40029,”errmsg”:”invalid code”}

第四步:拉取用户信息(需scope为snsapi_userinfo)

  • 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
  • http:GET(请使用https协议)
1
https://api.weixin.qq.com/sns/userinfo?access_token= `ACCESS_TOKEN` &openid= `OPENID` &lang=zh_CN

注意:这里调用的接口千万不要用下面这个:
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN(这个接口是用基础access_token和openID
来获取用户信息,前提是用户必须已经关注该公众号)

  • 参数说明
    参数说明

  • 返回说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
正确时返回的JSON数据包如下:
{

   "openid":" OPENID",

   " nickname": NICKNAME,

   "sex":"1",

   "province":"PROVINCE"

   "city":"CITY",

   "country":"COUNTRY",

    "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",

     "privilege":[

     "PRIVILEGE1"

     "PRIVILEGE2"

    ],

    "unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"

}
  • 返回参数说明
    返回参数说明

  • 错误时微信会返回JSON数据包如下(示例为openid无效):

    • {“errcode”:40003,”errmsg”:”invalid openid “}

教程

博文 来自: u012532350
没有更多推荐了,返回首页