微信公众号--微信网页授权

1:用户同意授权,获取code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

替换URL中的APPID&REDIRECT_URI等参数

尤其注意:由于授权操作安全等级较高,所以在发起授权请求时,微信会对授权链接做正则强匹配校验,如果链接的参数顺序不对,授权页面将无法正常访问

当用户访问并确认授权之后将转发至REDIRECT_URI”。

2:通过code换取网页授权access_token

https://api.weixin.qq.com/sns/oauth2/access_token
/**
 * 获取授权凭证token
 * @param key 应用appid
 * @param secret  应用密匙
 * @return json格式的字符串
 */
public static String getAccessToken(String appid, String secret,String code) {
	TreeMap<String, String> map = new TreeMap<>();
	map.put("appid", appid);
	map.put("secret", secret);
	map.put("code", code);
	map.put("grant_type", "authorization_code");
	String json = HttpReqUtil.HttpDefaultGetExecute(WechatConfig.GET_AUTH_TOKEN_URL, map,
			"");
	logger.debug("WechatUtil getAuthAccessToken,result: "+json);
	String result = null;
	WeixinAuthToken accessToken = JsonHelper.DeserializeObject(json, WeixinAuthToken .class);
	return accessToken ;
}
@Data
public class WeixinAuthToken {

	String access_token;
	Long expires_in;
	String refresh_token;
	String openid;
	String scope;
	String unionid;
	
}
{ 
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" 
}

获取openid和unionid 和网页系统的用户信息关联。

3:刷新access_token(如果需要)

https://api.weixin.qq.com/sns/oauth2/refresh_token
/**
 * 获取授权凭证token
 * @param key 应用appid
 * @param token 通过access_token获取到的refresh_token参数
 * @return json格式的字符串
 */
public static String refreshAccessToken(String appid, String token) {
	TreeMap<String, String> map = new TreeMap<>();
	map.put("appid", appid);
	map.put("grant_type", "refresh_token");
	map.put("refresh_token", token);
	String json = HttpReqUtil.HttpDefaultGetExecute(WechatConfig.REFRESH_AUTH_TOKEN_URL, map,
			"");
	logger.debug("WechatUtil getAuthAccessToken,result: "+json);
	String result = null;
	WeixinAuthToken accessToken = JsonHelper.DeserializeObject(json, WeixinAuthToken .class);
	return accessToken ;
}

4:拉取用户信息(需scope为 snsapi_userinfo)

https://api.weixin.qq.com/sns/userinfo
/**
 * 获取授权凭证token
 * @param openid 微信用户openid
 * @param token 通过access_token获取到的refresh_token参数
 * @return json格式的字符串
 */
public static String getWeixinSNSUser(String token,String openid) {
	TreeMap<String, String> map = new TreeMap<>();
	map.put("access_token", token);
	map.put("openid", openid);
	map.put("lang", "zh_CN");
	String json = HttpReqUtil.HttpDefaultGetExecute(WechatConfig.REFRESH_AUTH_TOKEN_URL, map,
			"");
	logger.debug("WechatUtil getAuthAccessToken,result: "+json);
	String result = null;
	WeixinUser  weixinUser = JsonHelper.DeserializeObject(json, WeixinUser .class);
	return accessToken ;
}
@Data
public class WeixinUser {
	String subscribe;
	String openid;
	String nickname;
	String sex;
	String language;
	String city;
	String province;
	String country;
	String headimgurl;
	String subscribe_time;
	String unionid;
	String remark;
	String groupid;
	String[] tagid_list;
	String subscribe_scene;
	String qr_scene;
	String qr_scene_str;
}

Http请求工具类

package weixin.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * Http连接工具类
 * @author huizhe.yu
 */
public class HttpReqUtil {

	private static int DEFAULT_CONNTIME = 5000;
	private static int DEFAULT_READTIME = 5000;
	
	public static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";
	public static final String GET_METHOD = "GET";
	public static final String POST_METHOD = "POST";

	/**
	 * http请求
	 * @param method 请求方法GET/POST
	 * @param path  请求路径
	 * @param timeout 连接超时时间 默认为5000
	 * @param readTimeout 读取超时时间 默认为5000
	 * @param data  数据
	 * @return
	 */
	private static String defaultConnection(String method, String path, int timeout, int readTimeout, String data)
			throws Exception {
		String result = "";
		URL url = new URL(path);
		if (url != null) {
			HttpURLConnection conn = getConnection(method, url);
			conn.setConnectTimeout(timeout == 0 ? DEFAULT_CONNTIME : timeout);
			conn.setReadTimeout(readTimeout == 0 ? DEFAULT_READTIME : readTimeout);
			if (StringUtils.isNoneBlank(data)) {
				OutputStream output = conn.getOutputStream();
				output.write(data.getBytes(DEFAULT_CHARACTER_ENCODING));
				output.flush();
			}
			if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				InputStream input = conn.getInputStream();
				result = IOUtil.inputStreamToString(input, DEFAULT_CHARACTER_ENCODING);
				conn.disconnect();
			}
		}
		return result;
	}

	/**
	 * 根据url的协议选择对应的请求方式
	 * @param method 请求的方法
	 * @return
	 * @throws IOException
	 */
	private static HttpURLConnection getConnection(String method, URL url) throws IOException {
		HttpURLConnection conn = null;
		if ("https".equals(url.getProtocol())) {
			SSLContext context = null;
			try {
				context = SSLContext.getInstance("SSL", "SunJSSE");
				context.init(new KeyManager[0], new TrustManager[] { new MyX509TrustManager() },
						new java.security.SecureRandom());
			} catch (Exception e) {
				throw new IOException(e);
			}
			HttpsURLConnection connHttps = (HttpsURLConnection) url.openConnection();
			connHttps.setSSLSocketFactory(context.getSocketFactory());
			connHttps.setHostnameVerifier(new HostnameVerifier() {
				@Override
				public boolean verify(String arg0, SSLSession arg1) {
					return true;
				}
			});
			conn = connHttps;
		} else {
			conn = (HttpURLConnection) url.openConnection();
		}
		conn.setRequestMethod(method);
		conn.setUseCaches(false);
		conn.setDoInput(true);
		conn.setDoOutput(true);
		return conn;
	}

	/**
	 * 设置参数
	 * @param map     参数map
	 * @param path    需要赋值的path
	 * @param charset 编码格式 默认编码为utf-8(取消默认)
	 * @return 已经赋值好的url 只需要访问即可
	 */
	public static String setParmas(Map<String, String> map, String path, String charset) throws Exception {
		String result = "";
		boolean hasParams = false;
		if (path != null && !"".equals(path)) {
			if (MapUtils.isNotEmpty(map)) {
				StringBuilder builder = new StringBuilder();
				Set<Entry<String, String>> params = map.entrySet();
				for (Entry<String, String> entry : params) {
					String key = entry.getKey().trim();
					String value = entry.getValue().trim();
					if (hasParams) {
						builder.append("&");
					} else {
						hasParams = true;
					}
					if (charset != null && !"".equals(charset)) {
						// builder.append(key).append("=").append(URLDecoder.(value,charset));
						builder.append(key).append("=").append(IOUtil.urlEncode(value, charset));
					} else {
						builder.append(key).append("=").append(value);
					}
				}
				result = builder.toString();
			}
		}
		return doUrlPath(path, result).toString();
	}

	/**
	 * 设置连接参数
	 * @param path 路径
	 * @return
	 */
	private static URL doUrlPath(String path, String query) throws Exception {
		URL url = new URL(path);
		if (StringUtils.isEmpty(path)) {
			return url;
		}
		if (StringUtils.isEmpty(url.getQuery())) {
			if (path.endsWith("?")) {
				path += query;
			} else {
				path = path + "?" + query;
			}
		} else {
			if (path.endsWith("&")) {
				path += query;
			} else {
				path = path + "&" + query;
			}
		}
		return new URL(path);
	}

	/**
	 * 默认的http请求执行方法,返回
	 * @param method 请求的方法 POST/GET
	 * @param path 请求path 路径
	 * @param map 请求参数集合
	 * @param data 输入的数据 允许为空
	 * @return
	 */
	public static String HttpDefaultExecute(String method, String path, Map<String, String> map, String data) {
		String result = "";
		try {
			String url = setParmas((TreeMap<String, String>) map, path, "");
			result = defaultConnection(method, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public static String HttpDefaultPostExecute(String path, Map<String, String> map, String data) {
		String result = "";
		try {
			String url = setParmas((TreeMap<String, String>) map, path, "");
			result = defaultConnection(POST_METHOD, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	public static String HttpDefaultGetExecute(String path, Map<String, String> map, String data) {
		String result = "";
		try {
			String url = setParmas((TreeMap<String, String>) map, path, "");
			result = defaultConnection(GET_METHOD, url, DEFAULT_CONNTIME, DEFAULT_READTIME, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}
package weixin.utils;

import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import common.util.JsonHelper;
import weixin.entity.WeixinTokenBase;

public class WechatUtil {
	
	protected static Logger logger = LoggerFactory.getLogger(WechatUtil.class);
	
	/**
	 * 获取授权凭证token
	 * @param key 应用appid
	 * @param secret  应用密匙
	 * @return json格式的字符串
	 */
	public static String getAccessToken(String appid, String secret) {
		TreeMap<String, String> map = new TreeMap<>();
		map.put("grant_type", "client_credential");
		map.put("appid", appid);
		map.put("secret", secret);
		String json = HttpReqUtil.HttpDefaultGetExecute(WechatConfig.GET_ACCESS_TOKEN_URL, map,
				"");
		logger.debug("WechatUtil getAccessToken,result: "+json);
		String result = null;
		WeixinTokenBase accessToken = JsonHelper.DeserializeObject(json, WeixinTokenBase.class);
		if (accessToken != null) {
			result = accessToken.getAccess_token();
		}
		return result;
	}

}

HTTPS 微信信任管理器:

package weixin.utils;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager; 
/**
 * @author yuhuizhe
 * 信任管理器 
 */
public class MyX509TrustManager implements X509TrustManager{
	// 检查客户端证书  
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    // 检查服务器端证书  
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
    }  
  
    // 返回受信任的X509证书数组  
    public X509Certificate[] getAcceptedIssuers() {  
        return null;  
    }  
}

package weixin.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * IO流工具类
 * huizhe.yu
 */
public class IOUtil {
	
	/**
	 * description:将输入流转换为字符串
	 * @param is     待转换为字符串的输入流
	 * @return 由输入流转换String的字符串
	 * @throws IOException
	 */
	public static String inputStreamToString(InputStream inputStream, String encoding) throws IOException {
		return IOUtils.toString(inputStream, encoding);
	}

	/**
	 * description: 将字符串转换为输入流
	 * @param sInputString 待转换为输入流的字符串
	 * @return
	 * @throws IOException
	 */
	public static InputStream toInputStream(String inputStr, String encoding) throws IOException {
		if (StringUtils.isEmpty(inputStr)) {
			return null;
		}
		return IOUtils.toInputStream(inputStr, encoding);
	}
	

	/**
	 * description:编码
	 * @param source
	 * @param encode
	 * @return
	 */
	public static String urlEncode(String source, String encode) {
		String result = source;
		try {
			result = URLEncoder.encode(source, encode);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * description:将输入流转换字节数组
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
		return IOUtils.toByteArray(inputStream);
	}

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值