整体流程:
微信授权登陆可分为四种:
1、移动端授权登陆;
2、网站应用端授权登陆(只支持扫码登陆, 如果是手机访问,那么就需要两部手机才能完成操作, 截图再扫描是不行的, 试过手机浏览器调起微信进行授权, 发现没有普遍应用, 只有京东、小米网页端有集成微信授权登陆,可能是有单独的接口 , 或者其他的交互流程及方法);
3、公众号、小程序授权登陆;
4、第三方平台(没用过)
一、 公众号授权流程及源码;(这些工具类可在SDK中查找)
1、客户服务端给出授权接口(这个地方给出微信访问客户服务端的回调地址, 注意这个地址是需要在公众平台 “网页授权”中配置的):
@RequestMapping(value = "/")
public String login(){
// String backUrl = "http://surenguangbo.com/suren/callBack";
String backUrl = "http://xxx.com/sur-api/web";
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
+ "appid="+ WXLogin.APPID
+ "&redirect_uri="+URLEncoder.encode(backUrl)
+ "&response_type=code"
+ "&scope=snsapi_userinfo"
+ "&state=STATE#wechat_redirect";
return "redirect:"+url;
}
2、此处直接获取code并请求微信拿到了客户的信息和openid 并给到H5页面, 这种方式的缺点只能将openid以get请求的形式, 拼接在后边;
@RequestMapping(value="web")
public String callBack(HttpServletRequest request) throws ClientProtocolException, IOException{
String code = request.getParameter("code");
// 获取openid
String url = "https://api.weixin.qq.com/sns/oauth2/access_token"
+ "?appid="+WXLogin.APPID
+ "&secret="+WXLogin.APPSECRET
+ "&code="+code
+ "&grant_type=authorization_code";
JSONObject wxuser = WXLogin.doGetjson(url);
String openid = wxuser.getString("openid");
System.out.println(openid);
String token = wxuser.getString("access_token");
System.out.println(token);
// 获取微信昵称、头像等用户信息
String infoUrl = "https://api.weixin.qq.com/sns/userinfo"
+ "?access_token="+token
+ "&openid="+openid
+ "&lang=zh_CN";
JSONObject userinfo = WXLogin.doGetjson(infoUrl);
/*
* {"city":"新乡","country":"中国",
* "headimgurl":"http://wx.qlogo.cn/mmopen/j2wX8eqnnnhd0Ie6WeosMYuWibO0zoKPsmPbtJzqB6UCiaN3bic8zkkcGqyZWoiamzWqTDVM8OV58JB30ibv1NPboAiaj6g3eTwYnr/0",
* "language":"zh_CN",
* "nickname":"sup",
* "openid":"oUWMrwX2009ZBdhqlKi-rD0OeMSI",
* "privilege":[],
* "province":"河南",
* "sex":1}
*/
// 获取用户的信息后,创建用户, 先判断用户是否存在, 不存在的话 创建, 存在的话省略 :
String name = userinfo.getString("nickname");
String photo = userinfo.getString("headimgurl");
String openidUser = userinfo.getString("openid");
String id = null;
String userName = "";
List<TSurenUser> userList = tSurenUserService.selectOneUser(openid);
if(userList != null && userList.size() > 0){
userName = WXLogin.filterEmoji(name, "1");
// 该用户存在的话, 更新下头像和名称;
userList.get(0).setPhoto(photo);
userList.get(0).setUsername(userName);
boolean b = tSurenUserService.updateUserNameAndPhoto(userList.get(0));
}else{
if(StringUtils.isNotBlank(openidUser) && StringUtils.isNotBlank(name) && StringUtils.isNotBlank(photo) ){
userName = WXLogin.filterEmoji(name, "1");
TSurenUser user = new TSurenUser();
user.setOpenid(openidUser);
user.setPhoto(photo);
user.setUsername(userName);
boolean b = tSurenUserService.saveUser(user);
}
}
return "redirect:http://xxx.com/sur/index.html?openid="+openidUser;
}
PS: 可以将这个接口拆分为两个接口, 一个将code返回给H5, 另外一个根据code查询当前的用户openid及用户信息;
二、 网站应用授权登陆:
1、同公众号授权流程一样, 此处直接上代码;但是需要注意几个问题:
(1)网站应用授权登陆, 是在“微信开放平台”进行参数配置;
(2)需要申请应用, 一些企业信息及网站应用的信息;
(3)需要申请开发者资质才有接口权限,应该是每年认证一次, 中国大陆认证费用300元人民币, 在公众平台申请认证也是需要费用的, 可能不需要重复收费;
(4)如果开放平台没有和公众号进行绑定, 那么同一个用户获取到的openid是不一样的, 有一个unionid好像是一样的, 具体没有往后研究, 有兴趣的可以测试下; (要在开放平台绑定微信公众号, 这样才能保证同一个用户的openid是一样的;)
(5)开放平台的appId和AppSecret是不一样的, 是 两套;
(6)第一步的获取code的地址是不一样的,主要是scope=snsapi_login
unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
//---------------- web 微信授权登陆
@RequestMapping(value = "/webLogin")
public String webLogin(){
String backUrl = "http://xxx.com/sur/callBackWeb";
String url = "https://open.weixin.qq.com/connect/qrconnect?"
+ "appid="+ WXLogin.WEBAPPID
+ "&redirect_uri="+URLEncoder.encode(backUrl)
+ "&response_type=code"
+ "&scope=snsapi_login";
return "redirect:"+url;
}
/**
* web端的回调地址
* @param request
* @return
* @throws ClientProtocolException
* @throws IOException
*/
@RequestMapping(value="callBackWeb")
public String callBackWeb(HttpServletRequest request, HttpServletResponse response) throws ClientProtocolException, IOException, ServletException {
String code = request.getParameter("code");
return "redirect:http://xxx.com/index.html?code="+code+"#/buy";
}
/**
* 获取openid
* @param request
* @param vo
* @param response
* @return
* @throws IOException
*/
@RequestMapping(value="getOpenId")
@ResponseBody
public Result getOpenId(HttpServletRequest request, @RequestBody IndexVO vo, HttpServletResponse response) throws IOException {
// String code = request.getParameter("code");
String code = request.getParameter("code");
if(StringUtils.isBlank(code) || "null".equals(code)){
code = vo.getCode();
if(StringUtils.isBlank(code) || "null".equals(code)){
return Result.error("未接收到code");
}
}
String url = "https://api.weixin.qq.com/sns/oauth2/access_token"
+ "?appid="+WXLogin.WEBAPPID
+ "&secret="+WXLogin.WEBAPPSECRET
+ "&code="+code
+ "&grant_type=authorization_code";
JSONObject wxuser = WXLogin.doGetjson(url);
String openid = wxuser.getString("openid");
System.out.println(openid);
String token = wxuser.getString("access_token");
System.out.println(token);
String infoUrl = "https://api.weixin.qq.com/sns/userinfo"
+ "?access_token="+token
+ "&openid="+openid
+ "&lang=zh_CN";
JSONObject userinfo = WXLogin.doGetjson(infoUrl);
/*
* {"city":"新乡","country":"中国",
* "headimgurl":"http://wx.qlogo.cn/mmopen/j2wX8eqnnnhd0Ie6WeosMYuWibO0zoKPsmPbtJzqB6UCiaN3bic8zkkcGqyZWoiamzWqTDVM8OV58JB30ibv1NPboAiaj6g3eTwYnr/0",
* "language":"zh_CN",
* "nickname":"supe",
* "openid":"oUWMrwX2009ZBdhqlKi-rD0OeMSI",
* "privilege":[],
* "province":"河南",
* "sex":1}
*/
// 获取用户的信息后,创建用户, 先判断用户是否存在, 不存在的话 创建, 存在的话省略 :
String name = userinfo.getString("nickname");
String photo = userinfo.getString("headimgurl");
String openidUser = userinfo.getString("openid");
String id = null;
String userName = "";
List<TSurenUser> userList = tSurenUserService.selectOneUser(openid);
if(userList != null && userList.size() > 0){
userName = WXLogin.filterEmoji(name, "1");
// 该用户存在的话, 更新下头像和名称;
userList.get(0).setPhoto(photo);
userList.get(0).setUsername(userName);
boolean b = tSurenUserService.updateUserNameAndPhoto(userList.get(0));
}else{
if(StringUtils.isNotBlank(openidUser) && StringUtils.isNotBlank(name) && StringUtils.isNotBlank(photo) ){
userName = WXLogin.filterEmoji(name, "1");
TSurenUser user = new TSurenUser();
user.setOpenid(openidUser);
user.setPhoto(photo);
user.setUsername(userName);
boolean b = tSurenUserService.saveUser(user);
}
}
response.addHeader("openidWeb",openidUser);
return Result.resData();
}
//---------------- web 微信授权登陆
至此两种方式的授权的过程, 其实大同小异, 不过细节需要注意;