1.关于Oauth2.0
首先要简单了解一下Oauth2.0,Oauth2.0是一种授权机制,主要用来颁发令牌
1.简单解释 :OAuth 2.0 的四种方式 - 阮一峰的网络日志 (ruanyifeng.com)
2.微信登录用到的是第一种方式:授权码
就可以看到本地服务器要和微信服务器有互动的
所以要通过内网穿透获取临时域名
2.配置内网穿透
1.使用NATAPP网站配置隧道,获取本地电脑的临时域名。
2.参考:NATAPP1分钟快速新手图文教程 - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
3.配置微信公众号测试号
1.地址:微信公众平台 (qq.com)
2.获取测试号信息appid和appsecret
3.配置js接口安全域名:就是natapp获取的临时域名
注意:这个域名不要带上http什么的
4.开启测试号网页授权功能并配置:点击修改把临时域名输入,这是微信服务器要回调你的服务器
4. 网页授权登录流程:查看[官方文档]微信开放文档 (qq.com)
1.用户同意授权之后获取code
2.获取code后换取access_token
3.获取用户信息
4.代码实现:
1.获取code 的js
function webAuthLogin() {
//thymeleaf语法获取值
var appId = [[${wxConfig.appId}]];
var openId = [[${session.openId}]];
var redirectUri = [[${redirectUri}]];
//根据重定向路径访问后台代码将code传过去,重定向路径里面就包括了自己的临时域名
if (openId == null) {
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+appId +
'&redirect_uri='+redirectUri +
'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
}else{
alert("您好:"+userInfo.nickname+",已经授权成功!");
}
}
2.获取code后换取access_token
//获取openid和access_token的连接
private static String getOpenId = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
//获取用户基本信息的连接
private static String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
@Autowired
private WxConfig wxConfig;//配置文件里面含有appid等信息
@Autowired
private HttpSession httpSession;
public String getCode(String code){
String getOpenIdUrl = getOpenId.replace("APPID", wxConfig.getAppId()).replace("APPSECRET", wxConfig.getAppSecret()).replace("CODE", code);
String response = HttpClientUtil.doGet(getOpenIdUrl);//根据code获取access_token
JSONObject jsonObject = JSONObject.parseObject(response);
String accessToken = jsonObject.get("access_token") == null ? null :jsonObject.get("access_token").toString();
String openId = jsonObject.get("openid") == null ? null : jsonObject.get("openid").toString();
httpSession.setAttribute("accessToken",accessToken);
httpSession.setAttribute("openId",openId);
httpSession.setAttribute("userInfo",getUserInfo(openId,accessToken));
//获取用户信息代码见下面
return "redirect:/";
}
3.获取用户信息
private JSONObject getUserInfo(String openId,String accessToken){//openId是用户唯一标识,accessToken是根据code换取的
String userInfoUrl = getUserInfo.replace("ACCESS_TOKEN",accessToken).replace("OPENID", openId);
String userInfo = HttpClientUtil.doGet(userInfoUrl);
JSONObject jsonObject = JSONObject.parseObject(userInfo);
return jsonObject;
}
注意:这两个变量是死的,后面需要的时候都是根据这个死变量替换一些值来当作请求获取数据
//获取openid和access_token的连接
private static String getOpenId = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
//获取用户基本信息的连接
private static String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
5.总体代码:
@Autowired
private WxConfig wxConfig;
@RequestMapping
public String index(Model model) throws UnsupportedEncodingException {
model.addAttribute("wxConfig",wxConfig);
// 进行编码
model.addAttribute("redirectUri", URLEncoder.encode(wxConfig.getServer()+"/webAuthLogin/getCode","UTF-8"));
return "login";
}
配置文件就不写了 ,就是appid ,appSecret,和自己的临时域名
function webAuthLogin() {
var appId = [[${wxConfig.appId}]];
var openId = [[${session.openId}]];
var redirectUri = [[${redirectUri}]];
if (openId == null) {
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+appId +
'&redirect_uri='+redirectUri +
'&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
}else{
alert("您好:"+userInfo.nickname+",已经授权成功!");
}
}
@Controller
@RequestMapping("webAuthLogin")
public class WebAuthLoginController {
//获取openid和access_token的连接
private static String getOpenId = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code";
//获取用户基本信息的连接
private static String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
@Autowired
private WxConfig wxConfig;
@Autowired
private HttpSession httpSession;
/**
* 微信网页授权回调
* @param code
* @return
*/
@RequestMapping("getCode")
public String getCode(String code){
String getOpenIdUrl = getOpenId.replace("APPID", wxConfig.getAppId()).replace("APPSECRET", wxConfig.getAppSecret()).replace("CODE", code);
String response = HttpClientUtil.doGet(getOpenIdUrl);
JSONObject jsonObject = JSONObject.parseObject(response);
String accessToken = jsonObject.get("access_token") == null ? null :jsonObject.get("access_token").toString();
String openId = jsonObject.get("openid") == null ? null : jsonObject.get("openid").toString();
httpSession.setAttribute("accessToken",accessToken);
httpSession.setAttribute("openId",openId);
httpSession.setAttribute("userInfo",getUserInfo(openId,accessToken));
return "redirect:/";
}
/**
* 获取微信用户信息
* @param openId
* @param accessToken
* @return
*/
private JSONObject getUserInfo(String openId,String accessToken){
String userInfoUrl = getUserInfo.replace("ACCESS_TOKEN",accessToken).replace("OPENID", openId);
String userInfo = HttpClientUtil.doGet(userInfoUrl);
JSONObject jsonObject = JSONObject.parseObject(userInfo);
return jsonObject;
}
}
注意:测试的时候用微信开发者工具哦!