用户通过点击微信公众平台中的菜单链接,进行网页授权获取openId进行无感应登录
微信菜单可以通过公众平台中进行配置 如果使用了微信服务器响应器地址,则需要使用代码生成微信菜单(生成微信菜单代码后期写)
配置的微信菜单的格式为域名+项目名/weChat/weChat/submenuView?view=(自定的菜单标识 )
package com.qike.webapp.controller;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.client.ClientProtocolException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.thinkgem.jeesite.common.sendtemp.WxUtils;
import com.thinkgem.jeesite.common.sendtemp.WxinConfig;
/***
* 用户点击微信菜单进行授权登录
*
* @author liuqiyu
* @date 2018年11月1日
*/
@Controller
@RequestMapping("/weChat/weChat")
public class WeChatControllet {
/***
* TODO 1.微信公众号定义子菜单 格式为 域名+项目名/weChat/weChat/submenuView?view=自定的菜单标识 TODO
* 2.网页授权地址需要改
*/
/***
* 微信网页授权后回调的地址,进行拼接openId,重定向到用户访问页面,完成授权登录
*
* @author liuqiyu
* @date 2018年11月1日
* @param request
* @param response
*/
@RequestMapping("/menuLinkCallback")
public void menuLink(HttpServletRequest request, HttpServletResponse response) {
String code = request.getParameter("code");// 微信返回code值,用code获取openid
String actionView = request.getParameter("actionView");// 根据该值判断要返回到的页面
try {
// 根据code值,进行获取用户的openId
Map<String, String> map = WxUtils.getAccess_tokenAndopenId(code);
// 判断用户是否是进行的绑定操作
if (null != actionView && WxinConfig.BINDING.equals(actionView)) {
// TODO 地址需要更改
response.sendRedirect(WxinConfig.DOMAINNAME + ".../binding.html?openid=" + map.get("openid"));
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 用户点击菜单后,进行网页授权地址拼接,然后返回到回调地址
*
* @author 刘骐毓
* @Date 2018年6月11日
* @param request
* @param response
* @param model
*/
@RequestMapping("/submenuView")
public void submenuview(HttpServletRequest request, HttpServletResponse response) {
try {
// view用来区分用户点击的子菜单
String view = request.getParameter("view");
String url = WxUtils.getOpenIdUrl(view, "state");
response.sendRedirect(url);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
网页授权的utils
package com.thinkgem.jeesite.common.sendtemp;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* 网页授权工具
*
* @author 刘骐毓
* @Date 2018年5月26日
*/
public class WxUtils {
/**
* 进行网页授权请求的地址
* @author 刘骐毓
* @Date 2018年9月7日
* @param actionView
* @param qrCodeNumber
* @param username
* @return
* @throws ClientProtocolException
* @throws IOException
*/
public static String getOpenIdUrl(String actionView, String username)
throws ClientProtocolException, IOException {
// 网页授权请求地址
String url = WxinConfig.OPENIDURL;
// 网页授权成功后的回调地址
String REDIRECT_URI = WxinConfig.REDIRECT_URI;
// 进行替换微信的秘钥
url = url.replace("APPID", URLEncoder.encode(WxinConfig.APPID, "UTF-8"));
url = url.replace("STATE", username);
// 进行拼接actionView 是自己附带的一个参数,用户网页回调后区进行的是那个菜单的操作
url = url.replace("REDIRECT_URI", URLEncoder
.encode(REDIRECT_URI + "?actionView=" + actionView, "UTF-8"));
// 返回授权地址
return url;
}
/**
* 根据code获取网页授权的accessToken和用户的openid
* @author 刘骐毓
* @Date 2018年9月7日
* @param code
* @param weixinloadpath
* @return
* @throws IOException
*/
public static Map<String, String> getAccess_tokenAndopenId(String code)
throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
// 微信平台秘钥
String appid = WxinConfig.APPID;
String secret = WxinConfig.SECRET;
// 根据授权后返回的code值和微信的密码获取用户的openId
String url = WxinConfig.ACCESS_CODE_BY_CODE;
url = url.replace("AppId", appid).replace("AppSecret", secret).replace("CODE", code);
// 进行请求
HttpGet get = new HttpGet(url);
// 获取响应
HttpResponse response = httpClient.execute(get);
// 获取响应的json
String jsonStr = EntityUtils.toString(response.getEntity(), "utf-8");
// 解析json字符串
JSONObject jsonTexts = (JSONObject) JSON.parse(jsonStr);
// 解析数据
Map<String, String> map = new HashMap<String, String>();
// 获取access_token(该token是网页授权的token)和openId
String access_token = "";
String openid = "";
// 进行具体获取
if (jsonTexts.get("access_token") != null) {
access_token = jsonTexts.get("access_token").toString();
map.put("access_token", access_token);
}
if (jsonTexts.get("openid") != null) {
openid = jsonTexts.get("openid").toString();
map.put("openid", openid);
}
// 返回解析数据
return map;
}
// sha1加密
public static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash) {
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
}
一些配置的信息
package com.thinkgem.jeesite.common.sendtemp;
/**
* 有关微信所需要的常量值
*
* @author 刘骐毓
* @Date 2018年5月25日
*/
public class WxinConfig {
// get请求获取accessToken的地址
public static final String GETUTL = "https://api.weixin.qq.com/cgi-bin/token";
// grant_type的值为获取永久二维码的参数
public static final String GRANT_TYPE = "client_credential";
// 公众号开发平台,开发者ID(AppID)
public static final String APPID = "********";
// 公众号开发平台,开发者密码(AppSecret)
public static final String SECRET = "****************";
// post请求获取ticket的地址
public static final String POSTURL = "https://api.weixin.qq.com/cgi-bin/qrcode/create";
// 获取openid请求的地址
public static final String OPENIDURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
// 获取openid时回调的函数
public static final String REDIRECT_URI = "该回调地址就是网页授权中设置的回调地址";
// 回调函数中请求的url
public static final String ACCESS_CODE_BY_CODE = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=AppId&secret=AppSecret&code=CODE&grant_type=authorization_code";
// jsapi_ticket请求获取地址
public static final String JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
// 用户关注时的事件状态
public static final String EventType_SUBSCRIBE = "subscribe";
// 用户取关时 的事件状态
public static final String EventType_UNSUBSCRIBE = "unsubscribe";
// 根据openid获取用户的详细信息
public static final String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
// 用户与微信进行绑定
public static final String BINDING = "binding";
// 项目域名
public static final String DOMAINNAME="域名";
}
具体配置信息,后面再进行说明