目录
auth协议介绍
微信登录接入流程
编码实现步骤介绍
请求获取code
使用code获取授权票据access_token
使用access_token获取用户信息
OAUTH(Open Authorization,开放授权)协议为用户资源的授权提供了一个安全,开发而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的账号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权。并且这是安全的。
基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统
1.用户点击“微信登录”的图标,请求使用微信登录
2.第三方应用,请求微信开放平台,获取code,传参中就有回调url。
3.用户确认登录第三方应用,微信开放平台回调第三方应用的url,带上code
4.第三方应用拿到code,再带上appid,appsecrect等等参数,继续请求微信开放平台,获取access_token(授权票据)
5.微信开放平台会将access_token返回给第三方应用。
6.第三方应用拿到access_token,获取用户信息。
接入条件(微信开放平台)
注入开发者账号
拥有一个已审核通过的网站应用。
文档地址:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN
第一步:请求CODE
请求地址
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
返回CODE
redirect_uri?code=CODE&state=STATE
第二步:通过code获取access_token
获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
返回JSON
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
错误的
{"errcode":40029,"errmsg":"invalid code"}
第三步:通过access_token调用接口
获取用户个人信息
http://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
返回JSON
第四步:实现网站自身业务
保存session
设置token
后台代码:
package cn.bdqn.controller;
import cn.bdqn.common.Dto;
import cn.bdqn.common.DtoUtil;
import cn.bdqn.common.IdWorker;
import cn.bdqn.common.UrlUtils;
import cn.bdqn.pojo.QgUser;
import cn.bdqn.service.QgLoginService;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.spi.ErrorCode;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
/**
* 第三方登录控制器
* @author hduser
*
*/
@Controller
@RequestMapping(value = "/vendors")
public class VendorsController {
@Resource
private QgLoginService qgLoginService;
/**
* 微信登录——第一步:获取code
* @param response
*/
@RequestMapping(value = "/wechat/login")
public void wechatLogin(HttpServletResponse response){
String qrconnect="https://open.weixin.qq.com/connect/qrconnect?appid=wx9168f76f000a0d4c&redirect_uri=http%3a%2f%2fj19h691179.iok.la%3a27105%2fvendors%2fwechat%2fcallback&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect";
try {
response.sendRedirect(qrconnect);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 微信登录——第二步:通过code换取access_token
* @param code
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(value = "/wechat/callback")
public void wechatCallback(@RequestParam String code, HttpServletRequest request, HttpServletResponse response) throws IOException{
String accessTokenUrl="https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx9168f76f000a0d4c&secret=8ba69d5639242c3bd3a69dffe84336c1&code="+
code+"&grant_type=authorization_code";
response.setContentType("text/html;charset=utf-8");
String json= UrlUtils.loadURL(accessTokenUrl);
Map wechatToken=JSON.parseObject(json, Map.class);
try {
//验证本地库是否存在该用户
QgUser user=qgLoginService.findByWxUserId(wechatToken.get("openid").toString());
if(user==null){//如果不存在则添加用户
user = new QgUser();
user.setWxUserId(wechatToken.get("openid").toString());
String id = IdWorker.getId();
user.setId(id);
qgLoginService.createQgUser(wechatToken.get("openid").toString(), id);
}
String token = qgLoginService.generateToken(user);
qgLoginService.save(token, user);
//返回前端处理
StringBuilder loginPage=new StringBuilder();
loginPage.append("http://j19h691179.iok.la:15614/index.html");
loginPage.append("?user_type=1&token="+token);
loginPage.append("&access_token="+wechatToken.get("access_token").toString());
loginPage.append("&expires_in="+wechatToken.get("expires_in").toString());
loginPage.append("&refresh_token="+wechatToken.get("refresh_token").toString());
loginPage.append("&openid="+wechatToken.get("openid").toString());
response.sendRedirect(loginPage.toString());
} catch (Exception e1) {
e1.printStackTrace();
}
}
/**
* 获取微信用户信息
* @param accessToken 微信会话凭据
* @param openid 微信用户唯一标识
* @return
*/
@RequestMapping(value = "/wechat/user/info", method = RequestMethod.GET,produces= "application/json")
public @ResponseBody
Dto wechatUserInfo(
@RequestParam String accessToken,
@RequestParam String openid){
try {
//加载用户信息
String userInfoJson=UrlUtils.loadURL("https://api.weixin.qq.com/sns/userinfo?access_token="
+accessToken
+"&openid="+ openid
);
Map userInfo=JSON.parseObject(userInfoJson, Map.class);
return DtoUtil.returnDataSuccess(userInfo);
} catch (Exception e) {
e.printStackTrace();
return DtoUtil.returnFail(e.getMessage(), "授权失败");
}
}
/**
* 会话保持
* 1、保持和itrip的会话
* 2、保持和wechat的会话
* @return
*/
// @RequestMapping(value = "/wechat/token/refresh", method = RequestMethod.POST,produces= "application/json")
// public @ResponseBody
// Dto wechatRefreshToken(HttpServletRequest request, HttpServletResponse response){
//
// String agent=request.getHeader("user-agent");
// String token=request.getHeader("token");
// String refreshToken=request.getHeader("refreshtoken");//此处header中的名称使用“_”不能获取
//
// try {
// //2、保持和wechat的会话
// String refreshTokenUrl="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=wx9168f76f000a0d4c&grant_type=refresh_token&refresh_token="+refreshToken.trim();
//
// String json=UrlUtils.loadURL(refreshTokenUrl);
// Map wechatToken=JSON.parseObject(json, Map.class);
// if(null!=wechatToken.get("errcode")){
// return DtoUtil.returnFail(wechatToken.get("errmsg").toString(), "置换token失败");
// }
//
// //返回ItripWechatTokenVO (整合了本地会话与微信会话)
// ItripWechatTokenVO wechatTokenVO=new ItripWechatTokenVO(token,
// Calendar.getInstance().getTimeInMillis()+TokenService.SESSION_TIMEOUT*1000,//2h有效期
// Calendar.getInstance().getTimeInMillis());
// wechatTokenVO.setAccessToken(wechatToken.get("access_token").toString());
// wechatTokenVO.setExpiresIn(wechatToken.get("expires_in").toString());
// wechatTokenVO.setRefreshToken(wechatToken.get("refresh_token").toString());
// wechatTokenVO.setOpenid(wechatToken.get("openid").toString());
// return DtoUtil.returnDataSuccess(wechatTokenVO);
//
// } catch (Exception e) {
// e.printStackTrace();
// return DtoUtil.returnFail(e.getMessage(), ErrorCode.AUTH_REPLACEMENT_FAILED);
// }
//
// }
}
打开地址http://