700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信开放平台下 公众号获取到用户的unionId(非三方平台模式)

微信开放平台下 公众号获取到用户的unionId(非三方平台模式)

时间:2019-12-17 07:10:29

相关推荐

微信开放平台下 公众号获取到用户的unionId(非三方平台模式)

实现功能: 通过扫公众号的二维码获取到用户的unionId

实现步骤:

1.申请一个微信开放平台

步骤参考:/article/8275fc8670af2546a13cf65d.html

2.微信开放平台下:公众账号绑定公众号

绑定结果如下:

3.微信公众号下:公众号设置里面设置这个三个域名

4.微信公众号下:点开网页授权域名

需要把这个文件下载并放入域名根目录下,并确保可以访问:如下图

5.微信公众号下,设置ip白名单

点击查看出现ip白名单设置页面

二、代码层面操作

1.获取公众号的appId和appSercret,见步骤5的截图

2.获取用户授权地址

https://open./connect/oauth2/authorize?appid=${你的公众号appId}&redirect_uri=${你的授权回调地址}&response_type=code&scope=snsapi_userinfo&state=${你的state}#wechat_redirect

注意:1.redirect_uri需要URLEncoder.encode加密,因为我没有前端页面所以我直接填的是我的后端代码的授权回调地址

2.state一般使用UUID.randomUUID().toString().replaceAll("-", "")

3. 前端将拿到的地址写入二维码

4. 用户微信扫码二维码

3.授权回调后处理

上代码

(1)常量类

// 全局常量类public class GlobalConstants {// 公众号的appIdpublic static final String GONGZHONGHAO_APP_ID = "你的appId";// 公众号的appSecretpublic static final String GONGZHONGHAO_SECRET = "你的appSecret";// 通过code获取token地址private final String GET_TOKEN_URL = "https://api./sns/oauth2/access_token";// 刷新token接口地址private final String REFREH_TOKEN_URL = "https://api./sns/oauth2/refresh_token";// 获取用户信息private final String GET_USER_URL = "https://api./sns/userinfo";}

(2)主流程代码实现

public class UserWechatController {@Autowiredprivate WechatUserService wechatUserService;@RequestMapping("/$APPID$/callback")@ApiOperation(value = "公众号回调地址")public String callBack(HttpServletRequest request) throws Exception{//得到code用于交换tokenString code = request.getParameter("code");String state = request.getParameter("state");log.info("用户授权回调,code---->"+code+",state---->"+state);//判断state是否合法if (StringUtils.isBlank(code) || StringUtils.isBlank(state)) {throw new BusinessException("code获取失败,请重新登录");}//用户授权后的code换取tokenMap<Object, Object> token = wechatUserService.getAccessToken(code, GlobalConstants.GONGZHONGHAO_APP_ID, GlobalConstants.GONGZHONGHAO_SECRET);log.info("用户授权回调,token------------------>"+token);//判断是否成功获取到了tokenif (token.get("errcode") != null) {throw new Exception("token获取失败,请重新登录");}if (token.get("access_token") == null || token.get("openid") == null) {throw new Exception("access_token拉取失败,请重新登录");}if (token.get("refresh_token") != null && token.get("openid") != null) {String openId = token.get("openid").toString();String refreshToken = token.get("refresh_token").toString();//刷新accesstokenMap userInfo = wechatUserService.refrehToken(GlobalConstants.GONGZHONGHAO_APP_ID, refreshToken);log.info("用户授权回调,token------------------>"+userInfo);//使用token交换获取用户信息WxchatUserReceiveReponse user = wechatUserService.getUserInfo(userInfo);// TODO 用户信息已经获取,后续流程自行处理} return "SUCCESS";}}

(3)Service类

public interface WechatUserService{/**getAccessToken*/Map getAccessToken(String code, String appId, String secret);/*** 刷新token处理* @return*/Map refrehToken(String appId, String refreshToken);/*** 通过token获取用户信息* @return*/WxchatUserReceiveReponse getUserInfo(Map token);}

(4)ServiceImpl实现类注:本来这个类也应该作为一个工具类,不要学我,用这个不规范写法

@Service@Slf4jpublic class WechatUserServiceImpl implements WechatUserService {/*** 通过code获取token* @return*/@Overridepublic Map getAccessToken(String code, String appid, String secret){//构建请求数据Map<String, String> t = new HashMap<String, String>();t.put("appid", appid);t.put("secret", secret);t.put("code", code);t.put("grant_type", "authorization_code");//调用httpclient处理请求得到返回json数据String returnJson = HttpClientUtil.get(GlobalConstants.GET_TOKEN_URL, t);Map token = (Map) JSONObject.parse(returnJson);return token;}/*** 刷新token处理* @return*/@Overridepublic Map refrehToken(String appid, String refresh_token){//构建请求参数Map<String, String> m = new HashMap<String, String>();m.put("appid", appid);m.put("grant_type", "refresh_token");m.put("refresh_token", refresh_token);//调用httpclient发出请求String resultJson = HttpClientUtil.get(GlobalConstants.REFREH_TOKEN_URL, m);Map refreshToken = (Map)JSONObject.parse(resultJson);return refreshToken;}/*** 通过token获取用户信息* @param token* @return*/public WxchatUserReceiveReponse getUserInfo(Map token){//构建请求数据Map u = new HashMap();u.put("access_token",token.get("access_token"));u.put("openid",token.get("openid"));u.put("lang","zh_CN");//调用httpclient处理请求得到用户信息json数据String userJson = HttpClientUtil.get(GlobalConstants.GET_USER_URL, u);log.info("用户授权回调,userJson------------------>"+userJson);//转换成用户对象WxchatUserReceiveReponse wxchatUser = JSONObject.parseObject(userJson, WxchatUserReceiveReponse.class);log.info("用户授权回调,token------------------>"+wxchatUser);return wxchatUser;}}

(5) http工具类

package com.rhpass.cloud.basic.message.wechat;import java.io.IOException;import java.io.InterruptedIOException;import .UnknownHostException;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.TimeUnit;import .ssl.SSLException;import .ssl.SSLHandshakeException;import mons.lang3.StringUtils;import org.apache.http.HttpEntityEnclosingRequest;import org.apache.http.HttpRequest;import org.apache.http.HttpResponse;import org.apache.http.NoHttpResponseException;import org.apache.http.client.HttpRequestRetryHandler;import org.apache.http.client.config.RequestConfig;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.protocol.HttpClientContext;import org.apache.http.client.utils.URIBuilder;import org.apache.http.config.Registry;import org.apache.http.config.RegistryBuilder;import org.apache.http.conn.ConnectTimeoutException;import org.apache.http.conn.ConnectionKeepAliveStrategy;import org.apache.http.conn.socket.ConnectionSocketFactory;import org.apache.http.conn.socket.LayeredConnectionSocketFactory;import org.apache.http.conn.socket.PlainConnectionSocketFactory;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.entity.ContentType;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.apache.http.protocol.HttpContext;import org.apache.http.util.EntityUtils;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.TypeReference;import mon.collect.Lists;public class HttpClientUtil {/** 默认连接超时时间毫秒 */public static int SO_TIME_OUT = 20000;/** 默认响应超时时间毫秒 */public static int CONNECTION_TIME_OUT = 20000;/*** 连接存活时间 默认60s*/private static final int CONNECTION_KEEP_ALIVE = 20 * 1000;private static CloseableHttpClient http = null;static {ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", plainsf).register("https", sslsf).build();PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);// 将最大连接数增加cm.setMaxTotal(500);// 将每个路由基础的连接增加cm.setDefaultMaxPerRoute(50);// 请求重试处理HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {if (executionCount >= 3) {// 如果已经重试了3次,就放弃return false;}if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试return true;}if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常return false;}if (exception instanceof InterruptedIOException) {// 超时return false;}if (exception instanceof UnknownHostException) {// 目标服务器不可达return false;}if (exception instanceof ConnectTimeoutException) {// 连接被拒绝return false;}if (exception instanceof SSLException) {// SSL握手异常return false;}HttpClientContext clientContext = HttpClientContext.adapt(context);HttpRequest request = clientContext.getRequest();// 如果请求是幂等的,就再次尝试if (!(request instanceof HttpEntityEnclosingRequest)) { return true; }return false;}};// 添加保持活性策略ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy() {@Overridepublic long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {long keepAlive = super.getKeepAliveDuration(response, context);if (keepAlive == -1) {keepAlive = CONNECTION_KEEP_ALIVE;}return keepAlive;}};http = HttpClients.custom().setConnectionManager(cm).setRetryHandler(httpRequestRetryHandler)// 定期清理连接池里的无效连接.evictExpiredConnections().setKeepAliveStrategy(keepAliveStrategy).setConnectionTimeToLive(CONNECTION_KEEP_ALIVE, TimeUnit.MILLISECONDS).build();}/*** 给定的URL连接POST数据,延时是固定的** @param urlvalue* @param param* @return*/public static String get(String urlvalue,Map<String, String> param) {return get(urlvalue, param, SO_TIME_OUT, CONNECTION_TIME_OUT);}/*** 给定的URL连接POST数据,延时是固定的** @param urlvalue* @param param* @return*/public static String get(String urlvalue, Map<String, String> param, int timeCout) {return get(urlvalue, param, timeCout, CONNECTION_TIME_OUT);}/*** 连接POST数据,延时可指定** @param urlvalue* @param param* @param socketTimeout* @param connectTimeout* @return* @throws IOException*/public static String get(String urlvalue, Map<String, String> param, int socketTimeout, int connectTimeout) {return getConnect(urlvalue, param, socketTimeout, connectTimeout);}private static String getConnect(String urlvalue, Map<String, String> param, int socketTimeout, int connectTimeout) {try {//创建URLBuilderURIBuilder uriBuilder=new URIBuilder(urlvalue);//设置参数if(param != null){param.forEach((key, value) ->{uriBuilder.setParameter(key,value);});}//2.创建HttpGet对象,设置URL地址HttpGet httpGet=new HttpGet(uriBuilder.build());RequestConfig config = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();httpGet.setConfig(config);CloseableHttpResponse response = http.execute(httpGet);return EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {}return "";}}

(6)参数接收类

package com.rhpass.cloud.basic.wechat.dto.reponse;import java.io.Serializable;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;@Data@ApiModel(value="WxchatUserReceiveReponse对象", description="微信用户信息")public class WxchatUserReceiveReponse implements Serializable{private static final long serialVersionUID = 1L;@ApiModelProperty(value = "openid")private String openid;@ApiModelProperty(value = "userId")private Integer userId;@ApiModelProperty(value = "昵称")private String nickname;@ApiModelProperty(value = "性别")private String sex;@ApiModelProperty(value = "省")private String province;@ApiModelProperty(value = "市")private String city;@ApiModelProperty(value = "头像")private String headimgurl;@ApiModelProperty(value = "用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)")private String privilege;@ApiModelProperty(value = "unionid")private String unionid;}

至此,本文的配置和代码实现结束。

如有错误,清帮忙纠正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。