前言:
继上篇文章在微信开放平台申请网站应用以后,我们就可以正式开始做微信扫码登录这个功能了,接下来这篇文章我将用最通俗易懂的话语让大家掌握整个微信扫码开发的流程,其实真的很简单,只要认真阅读官方文档,一步步的跟着往下做,就没有问题,小编相信你也可以,加油!
环境篇:
1.这是我通过审核的网站应用
网站应用微信登录的流程:
微信扫码登录的步骤
将上面那部分操作做好以后,我们就可以着手开发了,我们先从前端页面开始。
步骤(1): 在项目中引入js文件 ,调用微信后台接口,微信后台接收到用户请求后,会通过redirect_uri 将code 参数返回。
步骤(2):开发者在这个回调url 里面可以根据code获取AccessToken,得到用户的openID,当然其中涉及到一个AccessToken的过期和刷新问题。
步骤(3):接下来可以通过用户openID 和 AccessToken获取用户基本信息。
获取到用户信息以后,可以继续往下写逻辑,怎么让用户能够扫完码以后立马登录系统,这方面就需要自我再考虑一下。
步骤(1)
步骤(2)
1.在页面中引入如下JS文件地址:
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
2.在需要微信登录的地方实例以下JS对象:
var obj = new WxLogin({
self_redirect:true,
id:"login_container",
appid: "",
scope: "",
redirect_uri: "",
state: "",
style: "",
href: ""
});
3.前端页面的内容如下:
引入的Js:
import wechatLogin from '@/sjld/wechatLogin.js'
显示二维码图片的地方:
<!-- 微信扫码登录 -->
<a class="btn bt1" @click="wwIsShow=!wwIsShow"></a>
<div class="wxcss" v-show="wwIsShow" style="width:200px;height:200px" id="login_container">
二维码回调代码:
// 微信扫码登录
window.WxLogin({
self_redirect:true,
id:"login_container",
appid: "替换成你的APPID",
scope: "snsapi_login",
redirect_uri: "http://你的域名/wechatLogin",
state: "123",
style: "",
href: ""
})
上面这俩部分是我在项目中实际的引用情况,也可以在浏览器上访问二维码生成是否成功。
地址如下:
步骤(3)
我们来访问一下页面 ,看一下生成的微信二维码。
步骤(4)
WechatController
@ApiOperation(value = "1.9 微信授权登录")
@GetMapping(value = "/wechatLogin")
public void wechatLogin(HttpServletRequest request,HttpSession session) {
String code = request.getParameter("code");
String state = request.getParameter("state");
BosUserModel userModel = (BosUserModel) session.getAttribute("user");
WechatVo vo = new WechatVo();
vo.setAppId("替换成你的Appid");
vo.setAppSecret("替换成你的AppSecret");
vo.setCode(code);
vo.setUserModel(userModel);
weiService.wechatLogin(vo);
}
WeiService
@Override
public void wechatLogin(WechatVo vo) {
try {
//第1步,通过code 换取AccessToken
String url = WeiXinParamesUtil.GET_ACCESSTOKEN.replace("appId", vo.getAppId()).replace("{appid}", vo.getAppId()).replace("{secret}", vo.getAppSecret()).replace("{code}", vo.getCode());
JSONObject jsonObject = SendRequest.sendGet(url);
//获取返回的参数
String accessToken = jsonObject.getString("access_token");
String refreshToken = jsonObject.getString("refresh_token");
String openId = jsonObject.getString("openid");
int expires_in = jsonObject.getIntValue("expires_in");
//第2步,刷新AccessToken的值(通过refresh_token换取AccessToken的值)
if (expires_in > 7200) {
String refreshTokenUrl = WeiXinParamesUtil.REFRESH_TOKEN.replace("{appid}", WeiXinParamesUtil.APPID).replace("{refresh_token}", refreshToken).replace("{refresh_token}", refreshToken);
JSONObject refreshTokenObject = SendRequest.sendGet(refreshTokenUrl);
accessToken = refreshTokenObject.getString("access_token");
}
//第3步,检验授权凭证AccessToken是否有效
String checkAccessTokenUrl = WeiXinParamesUtil.CHECK_OUT_ACCESSTOKEN.replace("{access_token}", accessToken).replace("{open_id}", openId);
JSONObject jsonObject1 = SendRequest.sendGet(checkAccessTokenUrl);
if (jsonObject1.getString("errmsg").equals("ok")) {
//验证通过后进入下一步
//第4步, 获取用户个人信息
String getUserInfo_url = WeiXinParamesUtil.GET_SNS_USER_INFO.replace("{access_token}", accessToken).replace("{open_id}", openId);
JSONObject userObject = SendRequest.sendGet(getUserInfo_url);
//接收用户信息
//用户id
String nickname = userObject.getString("nickname");
String sex = userObject.getString("sex");
String province = userObject.getString("province");
String city = userObject.getString("city");
String country = userObject.getString("country");
String headImageUrl = userObject.getString("headimgurl");
String unionId = userObject.getString("unionid");
System.out.println("用户名称:----" + nickname);
}
} catch (Exception e) {
logger.error("微信登录失败", e);
}
}
SendRequest
//发送GET请求
public static JSONObject sendGet(String url) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
JSONObject jsonObject = null;
StringBuffer sb = new StringBuffer();
BufferedReader in = null;
try {
String urlName = url;
URL realUrl = new URL(urlName);
URLConnection conn = realUrl.openConnection();// 打开和URL之间的连接
conn.setRequestProperty("accept", "*/*");// 设置通用的请求属性
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
//针对群晖NAS请求,加一个Cookie
if (session.getAttribute("sid") != null) {
conn.addRequestProperty("Cookie", "id=" + session.getAttribute("sid"));
}
conn.setConnectTimeout(10000);
conn.connect();// 建立实际的连接
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));// 定义BufferedReader输入流来读取URL的响应
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
jsonObject = JSON.parseObject(sb.toString());
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
} finally {// 使用finally块来关闭输入流
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
System.out.println("关闭流异常");
}
}
return jsonObject;
}
WeiXinParamesUtil
package com.bos.util;
import com.alibaba.fastjson.JSONObject;
import com.bos.common.CommenUtil;
import com.bos.data.model.WeiUserInfoModel;
import com.bos.qiWechat.AesException;
import com.bos.qiWechat.WXBizMsgCrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 微信公众平台的参数
* @param
* @return
*/
public class WeiXinParamesUtil {
private Logger logger = LoggerFactory.getLogger(WeiXinParamesUtil.class);
/**
* 通过code 获取 access_token
*/
public static String GET_ACCESSTOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code";
/**
* 检验AccessToken是否有效
*/
public static String CHECK_OUT_ACCESSTOKEN = "https://api.weixin.qq.com/sns/auth?access_token={access_token}&openid={open_id}";
/**
* 微信开放平台获取用户信息
*/
public static String GET_SNS_USER_INFO = "https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={open_id}";
/**
* 刷新AccessToken
*/
public static String REFRESH_TOKEN = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={appid}&grant_type={refresh_token}&refresh_token={refresh_token}";
}
WechatVo
package com.bos.data.model.vo.setting;
import com.bos.data.model.BosUserModel;
import lombok.Data;
/**
* @Author tanghh
* @Date 2020/4/2 15:52
*/
@Data
public class WechatVo {
private String appId;
private String appSecret;
private String code;
private BosUserModel userModel;
}
效果图
控制台打印信息: