微信公众号开发--第三章 注册&签到&校验登录
作者:互联网
前言:本项目基于SSM,使用tomcat8、jdk8。
目录
微信公众号开发–第三章 注册&签到&校验登录
0、微信公众号-用户登录&查看信息-时序图
(高清html,文章末尾百度网盘链接自取)
1、获取用户基本信息&注册(对应时序图的步骤1-7)
1.1、接口代码(微信后端接口)
/**
* @DESCRIPTION : 与微信第三方交互,从而获取用户信息。
* 备注--1、本地启动前端服务获取code:
* 由于微信第三方的限制,获取code的操作,应该只能在微信客户端实现(官方文档貌似这个意思,我没写过test请求过)。
* 参考博文
* https://blog.csdn.net/Sharylala/article/details/105495723
* 的页面操作部分,获取code,而后将code作为入参调接口getUserInfo
*
* 备注--2、访问请求链接获取code:
* (自己微信号要关注自己的测试号二维码)
* 2.1、本地域名,设为 local.sharylala.test
* 2.2、回调地址,设为 local.sharylala.test
* 2.3、在微信开发者工具上,访问
* https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
* 其中APPID改写为你的appid值,REDIRECT_URI改写成你的 http://回调域名,
* scope为snsapi_base 时 scope=snsapi_base
* scope为snsapi_userinfo 时 scope=snsapi_userinfo(我测试只用过这个),
* state,重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节。eg: state=123
* 2.4、点击"同意"
* 2.5、自动跳转页面的地址上的code,五分钟有效
*
*
*
* @AUTHOR Sharylala
* @DATE : 2020/5/21 10:12 下午
* @param bean
* @param request
* @return: com.sharylala.common.util.Result
*/
@RequestMapping(value = "/getUserInfo", method = RequestMethod.POST)
@ResponseBody
public Result getUserInfo(@RequestBody UserBean bean, HttpServletRequest request) throws Exception {
log.info("----------AuthController:getUserInfo----------");
String code = bean.getCode();
if (code == null || "".equals(code)) {
return result(Constants.RESULT_MESSAGE_EMPTY,"code不能为空", null);
}
String openid = null;
JSONObject userInfo = new JSONObject();
WeChatAuth wa = new WeChatAuth(appid,appsecret);
/**
* 1、获取前端传来的code。
* 请求https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
* 获取access_token和openid。
* */
openid = wa.getOpenidByAuth(code);
if (null != openid) {
/**
* 2、根据access_token和openid,
* 请求https://api.weixin.qq.com/sns/userinfo?access_token=TOKEN&openid=OPENID&lang=zh_CN
* 拉取用户信息。
* */
userInfo = wa.getUserInfoByOpenid(openid);
//将拉取的基本信息存进用户表,略
} else {
return error("获取openid失败");
}
if (null == userInfo) {
userInfo = new JSONObject();
log.info("======微信用户信息获取失败====");
return error("获取用户信息获取失败");
}
return ok("获取用户信息获取成功",userInfo);
}
1.2、接口测试
1.2.1、获取code
点击同意后,链接里有code
1.2.2、获取用户信息
2、签到(对应时序图的步骤8-11)
2.1、接口代码(简化版,微信后端和后台接口)
微信后端签到接口common/sgin
/**
* @DESCRIPTION : 登陆验证获取tokenid接口
* @AUTHOR Sharylala
* @DATE : 2020/5/22 7:11 下午
* @param session
* @return: com.sharylala.common.util.Result
*/
@ResponseBody
@RequestMapping(value = "/sign", method = RequestMethod.GET, produces = "application/json")
public Result sign(HttpSession session) {
String url = Interface.getInstance().get("sign");
String result = (String) getWebClient(url, String.class);
log.info("---------sign:{}------", result);
JSONObject jsonResult = Common.strToJSONObject(result);
if (null == jsonResult) {
return error("接口请求错误");
}
String statusCode = jsonResult.getString("statusCode");
if ("200".equals(statusCode)) {
try {
log.info("======sessionId:{}======", session.getId());
JedisUtil.setValue(session.getId() + "_tokenid", jsonResult.getString("data"));
} catch (Exception e) {
e.printStackTrace();
}
}
return result(statusCode, jsonResult.getString("message"), jsonResult.getString("data"));
}
后台签到接口user/sign
/**
* @DESCRIPTION :获取tokenid
* @param request
* @param response
* @return: com.sharylala.common.util.Result
*/
@RequestMapping(value = "/sign", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public Result sign(@Context HttpServletRequest request, @Context HttpServletResponse response) {
String result = Constants.RESULT_MESSAGE_ERROR;
String message = "获取tokenid失败";
String tokenid = "";
String ip = "";
try {
tokenid = Constants.WECHAT_SERVICE_TOKENNAME + CommUtil.getUUID();
ip = CommUtil.getIpAddress(request);
JedisUtil.setValue(tokenid, ip, Constants.WECHAT_SERVICE_TIMEOUT);
result = Constants.RESULT_MESSAGE_SUCCESS;
message = "获取tokenid成功";
return result(result, message, tokenid);
} catch (Exception e) {
logger.info("tokenid is : " + tokenid + "===========ip is: " + ip);
logger.error(ip + "获取tokenid失败! /n 异常信息:" + e.getMessage(), e);
} finally {
logger.info("tokenid is : " + tokenid + "===========ip is: " + ip);
}
logger.info(message);
return result(result, message);
}
2.2、接口测试
3、校验登录
3.1、配置web.xml
<!-- 校验tokenid拦截器-->
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>com.sharylala.modules.wechatservice.filter.AuthFilter</filter-class>
<init-param>
<param-name>anonUrl</param-name>
<param-value>/auth/getUserInfo,/common/sign,/user/sign</param-value><!--过滤器添加例外url用,隔开-->
</init-param>
<init-param>
<param-name>authc</param-name><!--本系统拦截验证选项-->
<param-value>true</param-value><!--true需要拦截鉴权,安全性高,拦截未登录及无权限等访问;开发时可填false-->
</init-param>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/fileService/*</url-pattern><!--需要拦截验证的请求-->
<url-pattern>/business/*</url-pattern>
</filter-mapping>
3.2、实现Filter的拦截类代码
/**
* @DESCRIPTION: 校验tokenid拦截类
* @AUTHOR Sharylala
* @DATE 2020/5/23 8:41 下午
*/
public class AuthFilter implements Filter {
public final static Logger logger = LoggerFactory.getLogger(AuthFilter.class);
private boolean authc; //是否开启拦截
private String[] anonUrlArray; //不拦截的url
private final PathMatcher pathMatcher = new AntPathMatcher();
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String authcStr = filterConfig.getInitParameter("authc");
if (StringUtils.isNotBlank(authcStr)){
this.authc = Boolean.parseBoolean(authcStr);
}
String anonUrl = filterConfig.getInitParameter("anonUrl");
if (StringUtils.isNotBlank(anonUrl)) {
this.anonUrlArray = anonUrl.split(",");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
if (!authc) {
chain.doFilter(request, response);
return;
} else {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String currentURL = httpRequest.getServletPath();
//过滤白名单
if (isWhiteURL(currentURL)){
chain.doFilter(request, response);
return;
}
Cookie[] cookies = httpRequest.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("tokenid".equals(cookie.getName()) && StringUtils.isNotBlank(cookie.getValue())) {
//根据tokenid的值,去查redis有没有对应的ip(在签到接口里value就是用request的ip搞的)
String tokenid = cookie.getValue();
String redis = JedisUtil.getValue(tokenid);
if (StringUtils.isBlank(redis)) {
response.getWriter().print(JSON.toJSONString(new Result(Constants.RESULT_MESSAGE_EXIT, "登录超时,请重新登录")));
return;
}
String ip = CommUtil.getIpAddress(httpRequest);
//与request的ip对比
if (ip.equals(redis)) {
logger.info("====ip.equals(redis)====ip: " + ip + " redis: " + redis);
chain.doFilter(request, response);
return;
}
}
}
}
}
} catch (Exception e) {
logger.error("AuthFilter拦截器doFilter方法异常,", e);
}
response.getWriter().print(JSON.toJSONString(new Result("403", "please log in first!", null)));
}
@Override
public void destroy() {
//TODO Auto-generated method stub
}
private boolean isWhiteURL(String currentURL) {
for (String whiteURL : anonUrlArray) {
if (pathMatcher.match(whiteURL, currentURL)) {
return true;
}
}
return false;
}
}
3.3、测试
链接:https://pan.baidu.com/s/16-Wq-4VWXbJ_fkQupgLwag 密码:bj2k
标签:code,return,String,tokenid,签到,微信,校验,ip 来源: https://blog.csdn.net/Sharylala/article/details/106307665