一、准备

1、引入pom依赖

在要使用HttpClient的项目中加入依赖

<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>

2、添加httpclient工具类

把HttpClientUtils.java放入项目的util包

/**
* http请求客户端
*/
public class HttpClientUtils {
private String url;
private Map<String, String> param;
private int statusCode;
private String content;
private String xmlParam;
private boolean isHttps; public boolean isHttps() {
return isHttps;
} public void setHttps(boolean isHttps) {
this.isHttps = isHttps;
} public String getXmlParam() {
return xmlParam;
} public void setXmlParam(String xmlParam) {
this.xmlParam = xmlParam;
} public HttpClientUtils(String url, Map<String, String> param) {
this.url = url;
this.param = param;
} public HttpClientUtils(String url) {
this.url = url;
} public void setParameter(Map<String, String> map) {
param = map;
} public void addParameter(String key, String value) {
if (param == null)
param = new HashMap<String, String>();
param.put(key, value);
} public void post() throws ClientProtocolException, IOException {
HttpPost http = new HttpPost(url);
setEntity(http);
execute(http);
} public void put() throws ClientProtocolException, IOException {
HttpPut http = new HttpPut(url);
setEntity(http);
execute(http);
} public void get() throws ClientProtocolException, IOException {
if (param != null) {
StringBuilder url = new StringBuilder(this.url);
boolean isFirst = true;
for (String key : param.keySet()) {
if (isFirst) {
url.append("?");
isFirst = false;
}else {
url.append("&");
}
url.append(key).append("=").append(param.get(key));
}
this.url = url.toString();
}
HttpGet http = new HttpGet(url);
execute(http);
} /**
* set http post,put param
*/
private void setEntity(HttpEntityEnclosingRequestBase http) {
if (param != null) {
List<NameValuePair> nvps = new LinkedList<NameValuePair>();
for (String key : param.keySet())
nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
}
if (xmlParam != null) {
http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
}
} private void execute(HttpUriRequest http) throws ClientProtocolException,
IOException {
CloseableHttpClient httpClient = null;
try {
if (isHttps) {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} else {
httpClient = HttpClients.createDefault();
}
CloseableHttpResponse response = httpClient.execute(http);
try {
if (response != null) {
if (response.getStatusLine() != null)
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
// 响应内容
content = EntityUtils.toString(entity, Consts.UTF_8);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.close();
}
} public int getStatusCode() {
return statusCode;
} public String getContent() throws ParseException, IOException {
return content;
} }

二、获取access_token

在ApWxiController.java中添加如下方法

    @GetMapping("callback")
public String callback(String code, String state, HttpSession session){
System.out.println("callback被调用");
System.out.println("code:" + code);
System.out.println("state:" + state); if(StringUtils.isEmpty(code) || StringUtils.isEmpty(state)){
log.error("非法回调请求");
throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
} String sessionState = (String)session.getAttribute("wx_open_state");
if(!state.equals(sessionState)){
log.error("非法回调请求");
throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
} //携带code临时票据,和appid以及appsecret请求access_token和openid(微信唯一标识)
String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
//组装参数:?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
Map<String, String> accessTokenParam = new HashMap<>();
accessTokenParam.put("appid", ucenterProperties.getAppId());
accessTokenParam.put("secret", ucenterProperties.getAppSecret());
accessTokenParam.put("code", code);
accessTokenParam.put("grant_type", "authorization_code");
HttpClientUtils client = new HttpClientUtils(accessTokenUrl, accessTokenParam); String result = "";
try {
//发送请求:组装完整的url字符串、发送请求
client.get();
//得到响应
result = client.getContent();
System.out.println("result = " + result);
} catch (Exception e) {
log.error("获取access_token失败");
throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
} Gson gson = new Gson();
HashMap<String, Object> resultMap = gson.fromJson(result, HashMap.class); //失败的响应结果
Object errcodeObj = resultMap.get("errcode");
if(errcodeObj != null){
Double errcode = (Double)errcodeObj;
String errmsg = (String)resultMap.get("errmsg");
log.error("获取access_token失败:" + "code:" + errcode + ", message:" + errmsg);
throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
} //解析出结果中的access_token和openid
String accessToken = (String)resultMap.get("access_token");
String openid = (String)resultMap.get("openid"); System.out.println("accessToken:" + accessToken);
System.out.println("openid:" + openid); //在本地数据库中查找当前微信用户的信息
Member member = memberService.getByOpenid(openid); //TODO return null;
}

三、获取用户信息

1、根据openid查询用户是否已注册

业务接口:MemberService.java

/**
* 根据openid返回用户信息
* @param openid
* @return
*/
Member getByOpenid(String openid);

业务实现:MemberServiceImpl.java

@Override
public Member getByOpenid(String openid) {
QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("openid", openid);
return baseMapper.selectOne(queryWrapper);
}

2、根据access_token获取用户信息

@Autowired
private MemberService memberService; @GetMapping("callback")
public String callback(String code, String state, HttpSession session){
...
//根据access_token获取微信用户的基本信息
//根据openid查询当前用户是否已经使用微信登录过该系统
Member member = memberService.getByOpenid(openid);
if(member == null){ //向微信的资源服务器发起请求,获取当前用户的用户信息
String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo";
Map<String, String> baseUserInfoParam = new HashMap();
baseUserInfoParam.put("access_token", accessToken);
baseUserInfoParam.put("openid", openid);
client = new HttpClientUtils(baseUserInfoUrl, baseUserInfoParam); String resultUserInfo = null;
try {
client.get();
resultUserInfo = client.getContent();
} catch (Exception e) {
log.error(ExceptionUtils.getMessage(e));
throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
} HashMap<String, Object> resultUserInfoMap = gson.fromJson(resultUserInfo, HashMap.class);
if(resultUserInfoMap.get("errcode") != null){
log.error("获取用户信息失败" + ",message:" + resultMap.get("errmsg"));
throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
} String nickname = (String)resultUserInfoMap.get("nickname");
String headimgurl = (String)resultUserInfoMap.get("headimgurl");
Double sex = (Double)resultUserInfoMap.get("sex"); //用户注册
member = new Member();
member.setOpenid(openid);
member.setNickname(nickname);
member.setAvatar(headimgurl);
member.setSex(sex.intValue());
memberService.save(member);
} JwtInfo jwtInfo = new JwtInfo();
jwtInfo.setId(member.getId());
jwtInfo.setNickname(member.getNickname());
jwtInfo.setAvatar(member.getAvatar());
String jwtToken = JwtUtils.getJwtToken(jwtInfo, 1800); //携带token跳转
return "redirect:http://localhost:3000?token=" + jwtToken;
}

四、前端整合

components/AppHeader.vue
mounted() {
// 微信登录url token获取
this.token = this.$route.query.token
if (this.token) {
// 将token存在cookie中
cookie.set('guli_jwt_token', this.token, { domain: 'localhost' })
// 跳转页面:擦除url中的token
// 注意:window对象在created方法中无法被访问,因此要写在mounted中
window.location.href = '/'
}
},

微信登录4-开发回调URL的更多相关文章

  1. 微信登录2-生成授权URL

    一.准备工作 1.注册 微信开放平台:https://open.weixin.qq.com 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5.创建网 ...

  2. Java对接微信登录

    今天我们来对接微信开放平台的网站应用登录 首先上文档链接:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login ...

  3. 网站实现微信登录之回调函数中登录逻辑的处理--基于yii2开发的描述

    上一篇文章网站实现微信登录之嵌入二维码中描述了如何在自己的登录页面内嵌入登录二维码,今天的这篇文章主要是描述下在扫码成功之后微信重定向回网站后登录逻辑的处理,其实也就是验证身份信息,授权用户登录的逻辑 ...

  4. 网站实现微信登录之嵌入二维码——基于yii2开发的描述

    之前写了一篇yii2获取登录前的页面url地址的文章,然后发现自己对于网站实现微信扫码登录功能的实现不是很熟悉,所以,我会写2-3篇的文章来描述下一个站点如何实现微信扫码登录的功能,来复习下微信扫码登 ...

  5. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  6. PHP开发网站之微信登录、绑定

    )))刷新access_token()); ); ); curl_setopt($curlobj, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curlo ...

  7. iOS开发笔记14:微博/微信登录与分享、微信/支付宝支付

    产品中接入了微博/微信的第三方登录分享功能.微信和支付宝的第三方支付功能,之前在开发过程中涉及到这些部分,于是抽空将接入过程梳理了一遍. 1.微博.微信.支付宝SDK相关接入设置 (1)微博SDK S ...

  8. 你所误解的微信公众号开发、以及微信公众号网页授权、接收url跳转参数等问题

    前言:有一星期没跟新博客了,最近太忙.项目赶进度就没把时间花在博客上:今天来说说所谓的微信公众号开发和填坑记录: 微信公众号:运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因 ...

  9. 微信小程序开发——使用回调函数出现异常:TypeError: Cannot read property 'setData' of undefined

    关键技术点: 作用域问题——回调函数中的作用域已经脱离了调用函数了,因此需要在回调函数外边把this赋给一个新的变量才可以了. 业务需求: 微信小程序开发,业务逻辑需要,需要把获取手机号码的业务逻辑作 ...

随机推荐

  1. vue实现点击样式高亮

    •在data中定义即将渲染的数据,及active data() {     return {       active:'',//选中样式     };   }, 1 2 3 4 5 6 7 8 9 ...

  2. 【程序包管理】篇章3:CentOS平台下软件包安装方法总结

    1.软件包安装前的学习:程序包管理的基础知识 2.程序包安装的方法介绍: rpm文件的二进制包安装:Linux程序包管理之rpm安装总结 yum安装:Linux程序包管理之yum源安装 链接:本地yu ...

  3. HashMap知识点总结,这一篇算是总结的不错的了,建议看看!

    HashMap存储结构 内部包含了⼀个 Entry 类型的数组 Entry[] table.transient Entry[] table;(transient:表示不能被序列化)Entry类型存储着 ...

  4. day113:MoFang:种植园商城页面&充值集成Alipay完成支付的准备工作

    目录 1.种植园商城页面初始化 2.规划商品种类并且构建关于商品的模型类 3.解决APP打包编译之后的跨域限制 4.商品列表后端接口实现 5.前端获取商品列表并显示 6.种植园点击充值允许用户选择充值 ...

  5. MPEG2TS文件格式概述

    总结TS文件格式,早在几个月前就有了这个想法,但一直拖到今天才真正准备写一篇博文来介绍. 再不介绍的话,估计几月后又要去故纸堆里翻东西了,毕竟个人笔记中总结记录的东西太多,搞不好哪天给意外弄丢了. 1 ...

  6. svn怎么上传文件

    首先去网站下载TortoiseSVN,并安装   安装完后随便打开一个文件夹,如图,笔者在 E:\svn\ 文件下创建了一个simbo文件夹,选中并右键,出现了TortoiseSVN应用的选项,我们点 ...

  7. Linux音频编程--使用ALSA库播放wav文件

    在UBUNTU系统上使用alsa库完成了对外播放的wav文件的案例. 案例代码: /** *test.c * *注意:这个例子在Ubuntu 12.04.1环境下编译运行成功. * */ #inclu ...

  8. 前台生成JSON

    方法一 :在后台需要转换String - json let param = new URLSearchParams(); param.append('username', this.username) ...

  9. python在线练习

    不管学习那门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说大家都知道学编程语言一定要做项目才行. 这里整理了70个Python实战项目列表,都有完整且详细的教程,你可以从中选择自 ...

  10. 前端面试题归类-css

    一.说下盒模型? 有两种盒模型,W3C盒模型和IE盒模型通常说的"IE盒子模型"指的是IE5.5,IE6及其以后,盒模型都为 content-box当浏览器未设置<!doct ...