微信公众号获取OpenId(用户授权)(无需关注公众号)以及获取用户基本信息

上一个博客也写了微信公众号获取OpenId,但是现在这个和上一个有什么区别呢。

其实呢,是差不多的,只是这个是通过用户授权。


但是,又会有人问了,明明可以未授权获取到用户的openId,那我为什么要让用户进行授权呢,我偷偷的获取不就好了吗?

好像很有道理,但是呢,那微信又干嘛多一个接口呢?


其实,授权和未授权的区别就是:未授权的获取方式是需要用户关注你的公众号的,但是,授权的情况下,只要用户点击确定,用户是不需要去关注你的公众号的,你就可以获取到用户的openId以及用户的基本信息!!!

下面我讲一下流程:其实呢,流程是和上一个博客差不多的(请注意加红部分)(最后我会附上我的Utils)



1.在公众号后台设置回调的域名(大多情况下是你的项目)

开发-接口权限-网页账号-用户授权获取用户基础信息中修改


2.在页面上访问下面的网址

https://open.weixin.qq.com/connect/oauth2/authorize?appid=*******&redirect_uri=你回调的地址&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect

上面的会返回到你回调的地址?code=xxxxxxxxx

也就是说它会返回到你回调的地址并且带上code参数,一般情况下,回调的地址设置为后端的action即可,然后就可以获取到code了,当你获取到code,已经成功了一大半。


3.根据code获取到网页授权access_token(此token不是基础服务里的access_token,请记得区分),返回值内就含有openId


4.然后根据openId以及access_token你就可以获取用户基本信息了


下面我附上我的代码,已经封装好了,你只需修改appId以及secret即可,还有记得导入JSONObject的包哦,MyX509TrustManager就不贴了。


Utils:


package com.survey.common.wechat;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import com.survey.toysrus.model.WeChatAccessToken;
import com.survey.toysrus.model.WechatUserinfo;

import net.sf.json.JSONObject;

import com.survey.toysrus.model.WechatAccessTokenCheck;

public class weChatUtils {
	// 微信公众号的appId以及secret
	private static String appId = "";
	private static String secret = "";
	// 获取网页授权access_token的Url,和基础服务access_token不同,记得区分
	private static String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
	// 刷新网页授权access_token的Url,和基础服务access_token不同,记得区分
	private static String getRefreshAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
	// 检验授权凭证access_token是否有效,和基础服务access_token不同,记得区分
	private static String checkAccessTokenUrl = "https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID";
	// 获取用户信息的Url
	private static String getWXUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

	/**
	 * 根据code获取到网页授权access_token
	 * 
	 * @author Shen
	 * @param code
	 *            微信回调后带有的参数code值
	 */
	public static WeChatAccessToken getAccessToken(String code) {
		String url = weChatUtils.getAccessTokenUrl.replace("APPID", weChatUtils.appId).replace("SECRET", secret)
				.replace("CODE", code);
		JSONObject jsonObj=JSONObject.fromObject(httpRequest(url, "POST", null));
		return (WeChatAccessToken) JSONObject.toBean(jsonObj,WeChatAccessToken.class);
	}

	/**
	 * 根据在获取accessToken时返回的refreshToken刷新accessToken
	 * 
	 * @author Shen
	 * @param refreshToken
	 */
	public static WeChatAccessToken getRefreshAccessToken(String refreshToken) {
		String url = weChatUtils.getRefreshAccessTokenUrl.replace("APPID", weChatUtils.appId).replace("REFRESH_TOKEN",
				refreshToken);
		JSONObject jsonObj=JSONObject.fromObject(httpRequest(url, "POST", null));
		return (WeChatAccessToken) JSONObject.toBean(jsonObj,WeChatAccessToken.class);
	}

	/**
	 * 获取微信用户信息
	 * 
	 * @author Shen
	 * @param openId
	 *            微信标识openId
	 * @param accessToken
	 *            微信网页授权accessToken
	 */
	public static WechatUserinfo getWXUserInfoUrl(String openId, String accessToken) {
		String url = weChatUtils.getWXUserInfoUrl.replace("OPENID", openId).replace("ACCESS_TOKEN", accessToken);
		JSONObject jsonObj=JSONObject.fromObject(httpRequest(url, "POST", null));
		return (WechatUserinfo) JSONObject.toBean(jsonObj,WechatUserinfo.class);
	}

	/**
	 * 检验授权凭证accessToken是否有效
	 * 
	 * @author Shen
	 * @param openId
	 * @param accessToken
	 */
	public WechatAccessTokenCheck checkAccessToken(String openId, String accessToken) {
		String url = weChatUtils.checkAccessTokenUrl.replace("OPENID", openId).replace("ACCESS_TOKEN", accessToken);
		JSONObject jsonObj=JSONObject.fromObject(httpRequest(url, "POST", null));
		return (WechatAccessTokenCheck) JSONObject.toBean(jsonObj,WechatAccessTokenCheck.class);
	}

	/**
	 * get或者post请求
	 * 
	 * @author Shen
	 * @param requestUrl
	 * @param requestMethod
	 *            GET or POST 需要大写*
	 * @param outputStr
	 * @return
	 */
	public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
		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();
		} catch (ConnectException ce) {
			System.out.println("Weixin server connection timed out." + ce.getMessage());
		} catch (Exception e) {
			System.out.println("https request error:{}" + e.getMessage());
		}
		return buffer.toString();
	}

}
WeChatAccessToken:
package com.survey.toysrus.model;

/**
 * 此AccessToken不是基础模块的AccessToken,是一个特殊的网页授权access_token,请记得区分
 * 
 * @author Shen date : 2018-01-22
 */
public class WeChatAccessToken {
	/**
	 * 直接引用了微信的返回值,不使用驼峰等命名 access_token
	 * 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 expires_in
	 * access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid
	 * 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID scope
	 * 用户授权的作用域,使用逗号(,)分隔
	 */
	private String access_token;
	private int expires_in;
	private String refresh_token;
	private String openid;
	private String scope;

	// 额外的信息
	private int errcode;
	private String errmsg;

	public int getErrcode() {
		return errcode;
	}

	public void setErrcode(int errcode) {
		this.errcode = errcode;
	}

	public String getErrmsg() {
		return errmsg;
	}

	public void setErrmsg(String errmsg) {
		this.errmsg = errmsg;
	}

	public String getAccess_token() {
		return access_token;
	}

	public void setAccess_token(String access_token) {
		this.access_token = access_token;
	}

	public int getExpires_in() {
		return expires_in;
	}

	public void setExpires_in(int expires_in) {
		this.expires_in = expires_in;
	}

	public String getRefresh_token() {
		return refresh_token;
	}

	public void setRefresh_token(String refresh_token) {
		this.refresh_token = refresh_token;
	}

	public String getOpenid() {
		return openid;
	}

	public void setOpenid(String openid) {
		this.openid = openid;
	}

	public String getScope() {
		return scope;
	}

	public void setScope(String scope) {
		this.scope = scope;
	}

}







评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值