又一次好长时间没写博客了,呵呵哒 尴尬的笑一笑!
公司接了一个新项目客户那边比较急 所以决定实用jeecg 这种敏捷开发的开源框架开发!用了差不多三天时间才得以!功能实现的早 却一直懒得去写博客 额!好了废话不多说! 直接开始上代码吧!
需要实现的功能说明: 新用户点击登录——获取登录授权信息——同意——直接登录!
实现原理: 新用户的——授权后——获取openid——插入到数据库 下次登陆的时候直接判断有没有openid,没有的话插入 ,有的话则直接登录。对于微信公众号配置TOKEN、REDIRECT_URI、APPID什么的在此就不在详细说明了 不会的可以自行百度。
参考微信官方API:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
登录流程图:
一:
1 |
Controller实现: |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
package com.wuex.AppInterface; import com.baomidou.kisso.SSOHelper; import com.baomidou.kisso.SSOToken; import com.baomidou.kisso.common.util.HttpUtil; import com.wuex.AppInterface.interfaceUtil.CheckoutUtil; import com.wuex.AppInterface.interfaceUtil.WeiXinUtil; import com.wuex.AppInterface.weixinEntity.OAuthInfo; import com.wuex.wuIllegalreporting.entity.WuIllegalReportingEntity; import com.wuex.wuSuggestionoptimization.entity.WuSuggestionOptimizationEntity; import com.wuex.wufaultreport.entity.WuFaultReportEntity; import com.wuex.wumypoints.entity.WuMypointsEntity; import org.apache.commons.lang.StringUtils; import org.jeecgframework.core.enums.SysThemesEnum; import org.jeecgframework.core.util.SysThemesUtil; import org.jeecgframework.core.util.oConvertUtils; import org.jeecgframework.web.system.controller.core.LoginController; import org.jeecgframework.web.system.manager.ClientManager; import org.jeecgframework.web.system.pojo.base.TSRole; import org.jeecgframework.web.system.pojo.base.TSRoleUser; import org.jeecgframework.web.system.pojo.base.TSUser; import org.jeecgframework.web.system.service.SystemService; import org.jeecgframework.web.system.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.view.RedirectView; import javax.annotation.Resource; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import java.util.Map; import java.util.UUID; /** * 登陆初始化控制器 * */ @Controller @RequestMapping("/weixinApi") public class weixinLoginInterface { private static final Logger log = LoggerFactory.getLogger(LoginController.class); @Autowired private UserService userService; @Autowired private SystemService systemService; private OAuthInfo oAuthInfo; @Resource private ClientManager clientManager; /** * 微信引导页进入的方法 * * @return */ @RequestMapping(params = "loginByWeiXin") @ResponseBody public ModelAndView loginByWeiXin(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response) throws IOException { // 微信接口自带 2 个参数 String code = request.getParameter("code"); String state = request.getParameter("state"); //String code="1sdsd"; System.out.println("code = " + code + ", state = " + state); if (code != null && !"".equals(code)) { // 授权成功, 微信获取用户openID try { Map<String, String> result = WeiXinUtil.getAccess_token(code); String openid = result.get("Openid"); String access_token = result.get("AccessToken"); if (access_token == "null") { // Code 使用过 异常 System.out.println("Code 使用过 异常....."); return new ModelAndView("com/wuex/mobile/home");//跳转到提示页面提示:“code使用过异常” } // 数据库中查询微信号是否绑定平台账号 TSUser user = null; //openid="oBsOVwFh0HygDtJD-LFw7JtzBReM"; if (openid != "null"&&openid!=null) { user = userService.findUniqueByProperty(TSUser.class, "openid", openid); } if (user != null) { String roles = ""; System.out.println("登陆成功"); String hql="from WuIllegalReportingEntity as w where w.userId='"+user.getId()+"'"; List<WuIllegalReportingEntity> myIllegalReportingEntityList = systemService.findHql(hql); request.getSession().setAttribute("size",myIllegalReportingEntityList.size());//查询我的违法上报的建议数量 // request.setAttribute("size",myIllegalReportingEntityList.size()); String hql1="from WuFaultReportEntity as w where w.userId='"+user.getId()+"'"; List<WuFaultReportEntity> wuFaultReportEntityList = systemService.findHql(hql1); request.getSession().setAttribute("faultsize",wuFaultReportEntityList.size());//查询我的违法上报的建议数量 String hql2="from WuSuggestionOptimizationEntity as w where w.userId='"+user.getId()+"'"; List<WuSuggestionOptimizationEntity> wuSuggestionOptimizationEntityList = systemService.findHql(hql2); request.getSession().setAttribute("suggestsize",wuSuggestionOptimizationEntityList.size());//查询我的建议数量 request.getSession().setAttribute("tsuser", user);//登录成功后直接保存在session当中备用 String hql3="from TSUser as w where w.id='"+user.getId()+"'"; List<TSUser> TSUserEntityList = systemService.findHql(hql3);//查询我的积分列表 //只对应数据库中的一条数据 TSUser tsUserEntity = TSUserEntityList.get(0); request.setAttribute("tsUserEntity",tsUserEntity); List<TSRoleUser> rUsers = systemService.findByProperty(TSRoleUser.class, "TSUser.id", user.getId()); for (TSRoleUser ru : rUsers) { TSRole role = ru.getTSRole(); roles += role.getRoleName() + ","; } if (roles.length() > 0) { roles = roles.substring(0, roles.length() - 1); } modelMap.put("roleName", roles.length()>3?roles.substring(0,3)+"...":roles); modelMap.put("userName", user.getUserName().length()>5?user.getUserName().substring(0, 5)+"...":user.getUserName()); return new ModelAndView("com/wuex/mobile/home");//到时候换成APP登陆成功的跳转页面 } else { System.out.println("没有绑定账号进行自动绑定"); TSUser tsuser = new TSUser(); TSRoleUser tsroleuser=new TSRoleUser();//获得用户角色表 //获取微信信息 if (openid!=null&&openid!="null"&&access_token!=null&&access_token!="null") { //access_token="14_Wyrwa8gF6PCSN5KxGBCd00doGMnRM2Ocajesb7szGoqVjj1F9rzjIVV7J4AnZlww-2R2kQTC2Eirz46I_cuUYQ"; Map<String, String> userInfo = WeiXinUtil.getUserInfo(access_token, openid); tsuser.setOpenid(openid); if (!userInfo.isEmpty()) { tsuser.setUserName(userInfo.get("nickname")); //tsuser.setAddress(userInfo.get("city")); tsuser.setPortrait(userInfo.get("headimgurl"));//获取到微信头像 } // tsuser.setUserName("zhangsan");//测试数据 // tsuser.setCitizenNo("aasdsd"); tsuser.setUserType("1");//设为默认值 TSRole tsrole = systemService.findUniqueByProperty(TSRole.class, "id", "4028be81667bca5701667bf775f50052");//默认为普通用户 String roleid = tsrole.getId(); userService.saveOrUpdate(tsuser, null, roleid.split(",")); } //userService.save(tsuser); //String randomStr = CheckoutUtil.getRandomString(50); request.getSession().setAttribute("openid", openid); request.getSession().setAttribute("tsuser",tsuser);//保存到session当中 request.setAttribute("tsuser",tsuser); return new ModelAndView("com/wuex/mobile/home");//自动绑定微信账号后转到home页面 } } catch (Exception e) { e.printStackTrace(); } } // 未授权 // response.sendRedirect(WeiXinUtil.getStartURLToGetCode()); return new ModelAndView(new RedirectView(WeiXinUtil.getStartURLToGetCode())); } /** * 微信消息接收和token验证 * * @param model * @param request * @param response * @throws IOException */ @RequestMapping(params = "ownerCheck") @ResponseBody public void ownerCheck(HttpServletRequest request, HttpServletResponse response) throws IOException { System.out.println(111); boolean isGet = request.getMethod().toLowerCase().equals("get"); PrintWriter print; if (isGet) { // 微信加密签名 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (signature != null && CheckoutUtil.checkSignature(signature, timestamp, nonce)) { try { print = response.getWriter(); print.write(echostr); print.flush(); } catch (IOException e) { e.printStackTrace(); } } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
package com.wuex.AppInterface.interfaceUtil; import com.alibaba.fastjson.JSONObject; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.wuex.AppInterface.weixinConfig.weixinConfig; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class WeiXinUtil { /** * 第一步:用户同意授权,获取code(引导关注者打开如下页面:) * 获取 code、state */ public static String getStartURLToGetCode() { String takenUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect"; takenUrl= takenUrl.replace("APPID", weixinConfig.APPID ); takenUrl= takenUrl.replace("REDIRECT_URI", weixinConfig.REDIRECT_URI); takenUrl= takenUrl.replace("SCOPE", "snsapi_userinfo"); System.out.println(takenUrl); return takenUrl; } /** * 获取access_token、openid * 第二步:通过code获取access_token * */ public static Map<String, String> getAccess_token(String code)throws Exception{ Map<String, String> result = new HashMap<String, String>(); try { String authUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; // String authUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx12337d5790e2527c&secret=ee549239dbf1ecfd8f9f50fd885a273a&code="+ code + "&grant_type=authorization_code"; authUrl = authUrl.replace("APPID",weixinConfig.APPID); authUrl = authUrl.replace("SECRET", weixinConfig.SECRET); authUrl = authUrl.replace("CODE", code); JSONObject OpenidJSONO = doGetStr(authUrl); //OpenidJSONO可以得到的内容:access_token expires_in refresh_token openid scope String Openid = String.valueOf(OpenidJSONO.get("openid")); String AccessToken = String.valueOf(OpenidJSONO.get("access_token")); //用户保存的作用域 String Scope = String.valueOf(OpenidJSONO.get("scope")); String refresh_token = String.valueOf(OpenidJSONO.get("refresh_token")); result.put("Openid", Openid); result.put("AccessToken", AccessToken); result.put("scope", Scope); result.put("refresh_token", refresh_token); } catch (Exception e) { e.printStackTrace(); } return result; } /** * Get请求,方便到一个url接口来获取结果 * @param url * @return */ public static JSONObject doGetStr(String url){ DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); JSONObject jsonObject = null; try{ HttpResponse response = defaultHttpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if(entity != null){ String result = EntityUtils.toString(entity, "UTF-8"); jsonObject = JSONObject.parseObject(result); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return jsonObject; } /** * 获取用户信息 * * @param accessToken * @param openId * @return */ public static Map<String, String> getUserInfo(String accessToken, String openId) { Map<String, String> data = new HashMap(); String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN"; JsonObject userInfo = null; try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); String response = EntityUtils.toString(httpEntity, "utf-8"); Gson token_gson = new Gson(); userInfo = token_gson.fromJson(response, JsonObject.class); data.put("openid", userInfo.get("openid").toString().replaceAll("\"", "")); data.put("nickname", userInfo.get("nickname").toString().replaceAll("\"", "")); data.put("city", userInfo.get("city").toString().replaceAll("\"", "")); data.put("province", userInfo.get("province").toString().replaceAll("\"", "")); data.put("country", userInfo.get("country").toString().replaceAll("\"", "")); data.put("headimgurl", userInfo.get("headimgurl").toString().replaceAll("\"", "")); } catch (Exception ex) { ex.printStackTrace(); System.out.println("fail to request wechat user info. [error={}]"); } return data; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package com.wuex.AppInterface.interfaceUtil; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import java.io.IOException; import java.io.StringWriter; public class JacksonUtil { /** * bean转json格式或者json转bean格式, 项目中我们通常使用这个工具类进行json---java互相转化 */ private static ObjectMapper mapper = new ObjectMapper(); public static String bean2Json(Object obj) throws IOException { StringWriter sw = new StringWriter(); JsonGenerator gen = new JsonFactory().createJsonGenerator(sw); mapper.writeValue(gen, obj); gen.close(); return sw.toString(); } public static <T> T json2Bean(String jsonStr, Class<T> objClass) throws JsonParseException, JsonMappingException, IOException { return mapper.readValue(jsonStr, objClass); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
package com.wuex.AppInterface.interfaceUtil; import com.wuex.AppInterface.weixinConfig.weixinConfig; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Random; public class CheckoutUtil { /** * 验证签名 * * @param signature * @param timestamp * @param nonce * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arr = new String[] {weixinConfig.TOKEN, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典序排序 // Arrays.sort(arr); sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * * @param mByte * @return */ private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; } public static void sort(String a[]) { for (int i = 0; i < a.length - 1; i++) { for (int j = i + 1; j < a.length; j++) { if (a[j].compareTo(a[i]) < 0) { String temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } public static String getRandomString(int length){ //产生随机数 Random random=new Random(); StringBuffer sb=new StringBuffer(); //循环length次 for(int i=0; i<length; i++){ //产生0-2个随机数,既与a-z,A-Z,0-9三种可能 int number=random.nextInt(3); long result=0; switch(number){ //如果number产生的是数字0; case 0: //产生A-Z的ASCII码 result=Math.round(Math.random()*25+65); //将ASCII码转换成字符 sb.append(String.valueOf((char)result)); break; case 1: //产生a-z的ASCII码 result=Math.round(Math.random()*25+97); sb.append(String.valueOf((char)result)); break; case 2: //产生0-9的数字 sb.append(String.valueOf (new Random().nextInt(10))); break; } } return sb.toString(); } } |
PS:有问题的可以关注我的微信公众号:给我留言