1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 我的微信扫描二维码实现登录のJava

我的微信扫描二维码实现登录のJava

时间:2024-09-10 08:18:05

相关推荐

我的微信扫描二维码实现登录のJava

微信登录开发参考网址

微信官方文档の公众号微信公众平台接口测试账号申请微信公众平台接口在线调试网址

我的微信登录开发流程

配置一些基本数据

/*** 配置好一些需要用到的数据*/public class WechatConfig {//第三方用户唯一凭证,即appidpublic static final String APPID = "wxee746fb0e8f48f44";//第三方用户唯一凭证密钥,即appsecretpublic static final String SECRET = "bed208cba5e32cf8e92bbc2c96bd16da";//获取access_tokenpublic static final String ACCESS_TOKEN_URL = "https://api./cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";// 临时二维码public static final String QR_SCENE = "QR_SCENE";// 临时的字符串参数值public static final String QR_STR_SCENE = "QR_STR_SCENE";// 永久二维码public static final String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";// 永久二维码(字符串)public static final String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";// 通过accessToken 以及json 创建二维码 获取ticketpublic static final String CREATE_TICKET_PATH = "https://api./cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";// 通过ticket换取二维码public static final String SHOWQR_CODE_PATH = "https://mp./cgi-bin/showqrcode?ticket=TICKET";//此接口用于获取用户个人信息 UnionID机制public static final String GET_UNIONID_URL = "https://api./cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";}

生成二维码

获取access_token,access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。根据access_token 以及生成二维码需要的参数,生成带参数的二维码的ticket获取二维码ticket后,通过ticket换取二维码图片url展示到前端

/*** 生成带参数的二维码,扫描关注微信公众号,自动登录网站* @param modelMap* @return* @throws Exception*/@RequestMapping(value = "/wechat/login")@ResponseBodypublic Result wechatMpLogin(ModelMap modelMap) throws Exception {// String accessToken = wechatService.getAccessToken();String scene_str = "perFei." + new Date().getTime();String ticket = wechatService.createTempStrTicket("600", scene_str);if(ticket != null){String qrcodeUrl = wechatService.showqrcode(ticket);modelMap.put("qrcodeUrl", qrcodeUrl); //二维码的图片路径}modelMap.put("scene_str", scene_str);return Result.ok(null, modelMap);}

/*** 生成带参数的二维码的ticket* @param expire_seconds* @param scene_str* @return* @throws Exception*/@Overridepublic String createTempStrTicket(String expire_seconds,String scene_str) throws Exception {String access_token = this.getAccessToken();String url = WechatConfig.CREATE_TICKET_PATH;url = url.replaceAll("ACCESS_TOKEN",access_token);Map<String,String> strMap = new HashMap<String,String>();strMap.put("scene_str",scene_str);Map<String,Map<String,String>> mapMap = new HashMap<String,Map<String,String>>();mapMap.put("scene", strMap);Map<String,Object> paramsMap = new HashMap<String,Object>();paramsMap.put("expire_seconds", expire_seconds);paramsMap.put("action_name", WechatConfig.QR_STR_SCENE);paramsMap.put("action_info", mapMap);String data = new Gson().toJson(paramsMap);// 发送请求Map<String, Object> map = HttpClient.httpClientPost(url, data);String ticket = (String) map.get("ticket");return ticket==null?null:ticket;}/*** 获取access_tocken GET方法* @return* @throws Exception*/@Overridepublic String getAccessToken() throws Exception {String url = WechatConfig.ACCESS_TOKEN_URL;url = url.replaceAll("APPID", WechatConfig.APPID);url = url.replaceAll("SECRET", WechatConfig.SECRET);// 发送请求HttpClient client = new HttpClient(url);// 发送get请求client.get();// 获取到请求的结果 json格式的字符串,把json格式的字符串转换成对象或者Map集合String token_content = client.getContent();Map<String, Object> map = JSON.parseObject(token_content, Map.class);return map.get("access_token").toString();}/*** 获取二维码ticket后,通过ticket换取二维码图片展示* @param ticket* @return*/@Overridepublic String showqrcode(String ticket) {String qrcodeUrl = WechatConfig.SHOWQR_CODE_PATH;try {String encode = URLEncoder.encode(ticket, "utf-8");qrcodeUrl = qrcodeUrl.replaceAll("TICKET",encode);}catch (UnsupportedEncodingException e){e.printStackTrace();}return qrcodeUrl;}

验证检测是否扫描了二维码

主要是通过生成的二维码的参数进行判断用户是否有过扫描

/*** 检测登录* @param scene_str* @return*/@RequestMapping("/wechat/checkLogin")@ResponseBodypublic Map<String, Object> wechatMpCheckLogin(String scene_str) {// 根据scene_str查询数据库,获取对应记录WechatUser wechat = wechatService.getWechatUser(scene_str);Map<String, Object> returnMap = new HashMap<String, Object>();if (wechat != null ) {returnMap.put("openid", wechat.getOpenid());returnMap.put("result", "true");//登录成功} else {returnMap.put("result", "false");//登录失败}return returnMap;}

@Overridepublic WechatUser getWechatUser(String scene_str) {WechatUser wechatUser = wechatMapper.selectBySceneStr(scene_str);if(wechatUser != null){return wechatUser;}return wechatUser;}

微信验证签名信息和接收、处理、响应由微信服务器转发的用户发送给公众帐号的消息

/*** 自定义token, 用作生成签名,从而验证安全性*/private static final String TOKEN = "perFei";/*** 回调函数 post请求 接受、处理、响应微信信息* @param request* @param response* @throws Exception*/@PostMapping(value = "/wechat/callback")public void callbackPost(HttpServletRequest request, HttpServletResponse response) throws Exception{// TODO 接收、处理、响应由微信服务器转发的用户发送给公众帐号的消息// 将请求、响应的编码均设置为UTF-8(防止中文乱码)request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");System.out.println("请求进入");String result = "";try {//获得解析微信发来的请求Map<String,String> map = MessageUtil.parseXml(request);if (map != null && map.get("FromUserName").toString() != null){// 通过openid获取用户信息Map<String, Object> wechatUserMap = wechatService.getUserInfoByOpenid(map.get("FromUserName"));// 将数据写入到数据库中String event = map.get("EventKey");wechatService.insertWechatUser(wechatUserMap,event);}System.out.println("开始构造消息");//根据消息类型 构造返回消息result = MessageUtil.buildXml(map);System.out.println(result);if(result.equals("")){result = "未正确响应";}} catch (Exception e) {e.printStackTrace();System.out.println("发生异常:"+ e.getMessage());}response.getWriter().println(result);}/*** 回调函数 get请求 验证签名信息* @param request* @throws Exception*/@GetMapping(value = "/wechat/callback")public void callbackGet(HttpServletRequest request, HttpServletResponse response) throws Exception{// TODO 验证接口配置信息System.out.println("-----开始校验签名-----");// 接收微信服务器发送请求时传递过来的参数//微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。String signature = request.getParameter("signature");String timestamp = request.getParameter("timestamp"); //时间戳String nonce = request.getParameter("nonce"); //随机数String echostr = request.getParameter("echostr");//随机字符串//将token、timestamp、nonce三个参数进行字典序排序//并拼接为一个字符串String sortStr = sort(TOKEN,timestamp,nonce);//字符串进行shal加密String mySignature = shal(sortStr);// 校验微信服务器传递过来的签名 和 加密后的字符串是否一致, 若一致则签名通过if(!"".equals(signature) && !"".equals(mySignature) && signature.equals(mySignature)){System.out.println("-----签名校验通过-----");response.getWriter().write(echostr);response.getWriter().flush();}else {System.out.println("-----校验签名失败-----");}}/*** 参数排序* @param token* @param timestamp* @param nonce* @return*/public String sort(String token, String timestamp, String nonce) {String[] strArray = {token, timestamp, nonce};Arrays.sort(strArray);StringBuilder sb = new StringBuilder();for (String str : strArray) {sb.append(str);}return sb.toString();}/*** 字符串进行shal加密* @param str* @return*/public String shal(String str){try {MessageDigest digest = MessageDigest.getInstance("SHA-1");digest.update(str.getBytes());byte messageDigest[] = digest.digest();StringBuffer hexString = new StringBuffer();// 字节数组转换为 十六进制 数for (int i = 0; i < messageDigest.length; i++) {String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {hexString.append(0);}hexString.append(shaHex);}return hexString.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return "";}

工具类

package com.zcf.utils;import com.google.gson.Gson;import mons.httpclient.methods.ByteArrayRequestEntity;import mons.httpclient.methods.GetMethod;import mons.httpclient.methods.PostMethod;import mons.httpclient.methods.RequestEntity;import org.apache.http.Consts;import org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.*;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.conn.ssl.SSLContextBuilder;import org.apache.http.conn.ssl.TrustStrategy;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import .ssl.SSLContext;import java.io.IOException;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.text.ParseException;import java.util.HashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;/*** 可以发送Http请求的工具类(可以发送Https请求)*/public class HttpClient {// 请求的地址private String url;// 请求的参数private Map<String, String> param;private int statusCode;// 请求后,获取到的响应内容private String content;private String xmlParam;private boolean isHttps;public boolean isHttps() {return isHttps;}public void setHttps(boolean isHttps) {this.isHttps = isHttps;}public String getXmlParam() {return xmlParam;}public void setXmlParam(String xmlParam) {this.xmlParam = xmlParam;}public HttpClient(String url, Map<String, String> param) {this.url = url;this.param = param;}public HttpClient(String url) {this.url = url;}public void setParameter(Map<String, String> map) {param = map;}public void addParameter(String key, String value) {if (param == null)param = new HashMap<String, String>();param.put(key, value);}/*** 发送post请求* @throws ClientProtocolException* @throws IOException*/public void post() throws ClientProtocolException, IOException {HttpPost http = new HttpPost(url);setEntity(http);execute(http);}/*** 发送put请求* @throws ClientProtocolException* @throws IOException*/public void put() throws ClientProtocolException, IOException {HttpPut http = new HttpPut(url);setEntity(http);execute(http);}/*** 发送get请求* @throws ClientProtocolException* @throws IOException*/public void get() throws ClientProtocolException, IOException {if (param != null) {StringBuilder url = new StringBuilder(this.url);boolean isFirst = true;for (String key : param.keySet()) {if (isFirst)url.append("?");elseurl.append("&");url.append(key).append("=").append(param.get(key));}this.url = url.toString();}HttpGet http = new HttpGet(url);execute(http);}/*** set http post,put param*/private void setEntity(HttpEntityEnclosingRequestBase http) {if (param != null) {List<NameValuePair> nvps = new LinkedList<NameValuePair>();for (String key : param.keySet())nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数}if (xmlParam != null) {http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));}}/*** 真正发送请求的方法* @param http* @throws ClientProtocolException* @throws IOException*/private void execute(HttpUriRequest http) throws ClientProtocolException,IOException {CloseableHttpClient httpClient = null;try {if (isHttps) {SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {// 信任所有public boolean isTrusted(X509Certificate[] chain,String authType)throws CertificateException {return true;}}).build();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();} else {httpClient = HttpClients.createDefault();}CloseableHttpResponse response = httpClient.execute(http);try {if (response != null) {if (response.getStatusLine() != null)statusCode = response.getStatusLine().getStatusCode();HttpEntity entity = response.getEntity();// 响应内容content = EntityUtils.toString(entity, Consts.UTF_8);}} finally {response.close();}} catch (Exception e) {e.printStackTrace();} finally {httpClient.close();}}public int getStatusCode() {return statusCode;}public String getContent() throws ParseException, IOException {return content;}/*** httpClient-Post请求* @param url 请求地址* @param params post参数* @return* @throws Exception*/public static Map<String, Object> httpClientPost(String url, String params) throws Exception {mons.httpclient.HttpClient client = new mons.httpclient.HttpClient();client.getParams().setContentCharset("UTF-8");PostMethod httpPost = new PostMethod(url);try {RequestEntity requestEntity = new ByteArrayRequestEntity(params.getBytes("utf-8"));httpPost.setRequestEntity(requestEntity);client.executeMethod(httpPost);String response = httpPost.getResponseBodyAsString();Map<String, Object> map = new Gson().fromJson(response, Map.class);return map;} catch (Exception e) {throw new RuntimeException(e);} finally {httpPost.releaseConnection();}}/*** httpClient-Get请求* @param url 请求地址* @return* @throws Exception*/public static Map<String, Object> httpClientGet(String url) throws Exception {mons.httpclient.HttpClient client = new mons.httpclient.HttpClient();client.getParams().setContentCharset("UTF-8");GetMethod httpGet = new GetMethod(url);try {client.executeMethod(httpGet);String response = httpGet.getResponseBodyAsString();Map<String, Object> map = new Gson().fromJson(response, Map.class);return map;} catch (Exception e) {throw e;} finally {httpGet.releaseConnection();}}}

package com.zcf.utils;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import javax.servlet.http.HttpServletRequest;import java.io.InputStream;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;/*** @author zhangchuanfei* @create -04-12-23:46*/public class MessageUtil {/*** 解析微信发来的请求(XML)* @param request* @return map* @throws Exception*/public static Map<String,String> parseXml(HttpServletRequest request) throws Exception {// 将解析结果存储在HashMap中Map<String,String> map = new HashMap<String,String>();// 从request中取得输入流InputStream inputStream = request.getInputStream();//System.out.println("获取输入流");// 读取输入流SAXReader reader = new SAXReader();Document document = reader.read(inputStream);// 得到xml根元素Element root = document.getRootElement();// 得到根元素的所有子节点List<Element> elementList = root.elements();// 遍历所有子节点for (Element e : elementList) {System.out.println(e.getName() + "|" + e.getText());map.put(e.getName(), e.getText());}// 释放资源inputStream.close();inputStream = null;return map;}/*** 根据消息类型 构造返回消息*/public static String buildXml(Map<String,String> map) {String result;String msgType = map.get("MsgType").toString();//System.out.println("MsgType:" + msgType);if(msgType.toUpperCase().equals("TEXT")){result = buildTextMessage(map, "亲,有什么可以帮到您的?");}else{String fromUserName = map.get("FromUserName");// 开发者微信号String toUserName = map.get("ToUserName");result = String.format("<xml>" +"<ToUserName><![CDATA[%s]]></ToUserName>" +"<FromUserName><![CDATA[%s]]></FromUserName>" +"<CreateTime>%s</CreateTime>" +"<MsgType><![CDATA[text]]></MsgType>" +"<Content><![CDATA[%s]]></Content>" +"</xml>",fromUserName, toUserName, getUtcTime(),"登录成功");// "请回复如下关键词:\n文本\n图片\n语音\n视频\n音乐\n图文");}return result;}/*** 构造文本消息** @param map* @param content* @return*/private static String buildTextMessage(Map<String,String> map, String content) {//发送方帐号String fromUserName = map.get("FromUserName");// 开发者微信号String toUserName = map.get("ToUserName");/*** 文本消息XML数据格式*/return String.format("<xml>" +"<ToUserName><![CDATA[%s]]></ToUserName>" +"<FromUserName><![CDATA[%s]]></FromUserName>" +"<CreateTime>%s</CreateTime>" +"<MsgType><![CDATA[text]]></MsgType>" +"<Content><![CDATA[%s]]></Content>" + "</xml>",fromUserName, toUserName, getUtcTime(), content);}private static String getUtcTime() {Date dt = new Date();// 如果不需要格式,可直接用dt,dt就是当前系统时间DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");// 设置显示格式String nowTime = df.format(dt);long dd = (long) 0;try {dd = df.parse(nowTime).getTime();} catch (Exception e) {}return String.valueOf(dd);}}

package com.zcf.utils;import lombok.AllArgsConstructor;import lombok.Data;import java.io.Serializable;/*** @author zhangchuanfei* @create -04-19-10:25*/@Data@AllArgsConstructorpublic class Result implements Serializable {private static final long serialVersionUID = 1L;/*** 状态码*/private Integer code;/*** 信息*/private String info;/*** 数据*/private Object data;public static Result ok(String info, Object data) {return new Result(ResultEnum.OK.getCode(), info, data);}public static Result ok() {return ok(null,null);}public static Result error(Integer code, String info) {return error(code, info,null);}public static Result error(Integer code, String info, Object data) {return new Result(code, info, data);}public static Result error(ResultEnum resultEnum) {return error(resultEnum,null);}public static Result error(ResultEnum resultEnum, Object data) {return error(resultEnum.getCode(), resultEnum.getInfo(),data);}}

开发中需要有自己的服务器资源,我使用的是NATAPP内网穿透,使用的教程很简单,百度一下就可以了。

到这里基本上就完成了,不用多说了,登录成功之后根据个人的需要返回页面。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。