一,流程:
1,用户请求微信登录
2,第三方应用请求微信开放平台,获取code,传参中就有回调url
3,用户确认登录第三方应用,微信开放平台回调第三方应用的一个url,带上code
4,第三方应用拿到code,再带上appid,appsecrect等参数,继续请求微信开放平台,获取access_token(授权票据)
5,微信开放平台会将access_token返回给第三方应用
6,第三方应用拿到access_token,获取用户信息
二,接入条件
1,注册开发者账号
进入 微信开放平台 页面申请账号
2,拥有一个已审核通过的网站应用
进入 微信开放平台--网站应用开发--创建应用,后会获取appid,secret参数
三,代码实现
//公共项目,创建工具类,用于访问URL,对返回值做封装
package cn.bdqn.common;
public class UrlUtils{
public static String loadURL(String urlStr){
try{
URL url = new URL(urlStr);
HttpUrlConnection urlConnection = (HttpUrlConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
String responseStr = ConvertToString(inputStream);
return responseStr;
}catch(IOException e){
e.printStackTrace();
return null;
}
}
//把流转化为String
public static String ConvertToString(InputStream inputStream){
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(isr);
StringBuilder result = new StringBuilder();
String line = null;
try{
while((line = br.readLine()) != null){
result.append(line = "\n");
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
isr.close();
inputStream.close();
br.close();
}catch(IOException e){
e.sprintStackThace();
}
}
}
}
····················································································
//消费者项目
//创建配置类
package cn.bdqn.config;
@Component
@ConfigurationProperties(prefix = "wechat") // 给属性注入配置文件里的值
public class WechatConfig {
private String appId; //在微信开放平台创建应用后会获得appId,appSecret,在配置文件中获取
private String appSecret;
//回调Url,要能外网访问(花生壳转件可以做内网穿透),使用urlEncode对链接编码
private String redirectUrl;
//生成get/set方法略
}
·············································································
//消费者controller
package cn.bdqn.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.bdqn.common.Dto;
/**
*微信登录
*/
@Controller
@RequestMapping(value = "/vendors")
public class VendorController {
@Resource
private WechatConfig wechatConfig;
@Resource
private QgLoginService qgLoginService; //消费者业务层接口,对登录的业务操作
/**
*微信登录第一步:请求获取code
*@param response
*@return
*/
@RequestMapping(value = "/wechat/login")
public void veChatLogin(HttpServletResponse response){
StringBuilder sb = new StringBuilder("");
sb.append("https://open.weixin.qq.com/connect/qrconnect?");
sb.append("appid=");
sb.append(wechatConfig.getAppid());
sb.append("&redirect_uri=");
sb.append(wechatConfig.getRedirectUrl());
sb.append("&response_type=code");
sb.append("&scope=snsapi_login&state=STATE#wechat_redirect");
//重定向
try{
response.sendRedirect(sb.toString());
}catch(IOException e){
e.pringStackTrace();
}
}
/**
*微信登录第二,三步:通过code获取access_token,通过access_token获取用户信息并登录首页
*执行了第一步方法后,会通过回调URL调用此方法
*@param code
*@param response
*@param request
*@return
*/
@RequestMapping(value = "/wechat/callback")
public void veChatCallBack(@RequestParam String code,HttpServletResponse response,
HttpServletRequest request){
// 对回调URL“http://localhost:8082/vendors/wechat/callback"进行外网穿透和编码
// “http://localhost:8082” 可以用花生壳软件内网穿透
// “穿透路径/vendors/wechat/callback” 用urlEncode在线编码后获得回调URL,
也是wechatConfig.getRedirectUrl()的值
//第二步
StringBuilder accesstokenUrl = new StringBuilder("");
sb.append("https://api.weixin.qq.com/sns/oauth2/access_token?");
sb.append("appid=");
sb.append(wechatConfig.getAppid());
sb.append("&secret=");
sb.append(wechatConfig.getAppSecret());
sb.append("&code="+code);
sb.append("&grant_type=authorization_code");
//调用URL请求工具类,把返回流转为String
String accesstoken = UrlUtils.loadUrl(accesstokenUrl.toString());
//转为MAP
Map<String,Object> accesstokenMap = JSON.parseObject(accesstoken,Map.class);
//第三步
StringBuilder userinfoUrl = new StringBuilder("");
sb.append("https://api.weixin.qq.com//sns/userinfo?");
sb.append("access_token="+accesstokenMap.get("access_token").toString());
sb.append("&apenid="+accesstokenMap.get("openid").toString());
String userinfo = UrlUtils.loadUrl(userinfoUrl.toString());
Map<String,Object> userinfoMap = JSON.parseObject(userinfo,Map.class);
//拿到用户信息,然后做业务操作
//跳转到首页
//注意,首页的 穿透路径 需要在微信开放平台创建应用时在授权回调域里需要配置,不然不会访问
StringBuilder indexUrl = new StringBuilder("");
sb.append("http://路径+端口的穿透路径/index.xml");
try{
response.sendRedirect(indexUrl.toString());
}catch(IOException e){
e.pringStackTrace();
}
}
}