赞
踩
思路
1、Vue前端页面获取一个公众号的二维码,不是普通二维号,是带有场景值的
2、java后端接收前端的请求,生成一个带时效性的二维码链接返回给前端
3、公众号平台配置服务器接口地址
4、接收到关注或扫码请求并相应处理
5、前端轮询状态,如果检查到验证通过进到下一页面
前端页面
vue代码
- wxlogin() {
- this.$showLoading();
- getTempQrCode(this.token).then((res) => {
- console.log("res==========",res);
- this.$closeLoading();
- this.imageUrl = objToStr(res.data.message);
- this.loginType='wx'
- setTimeout(() => {
- this.check();
- }, 1000);
- })
- },
java代码
- @RequestMapping(value = "/getTempQrCode", method = RequestMethod.GET)
- public Result<?> getTempQrCode(@RequestParam(name = "scene_str", required = true) String sceneStr) {
-
- WeixinHelper.setAppId(appid);
- WeixinHelper.setSecret(secret);
- String result = WeixinHelper.createTempQrCode(WeixinHelper.getAccessToken(), sceneStr);
- return Result.ok(result);
- }
-
-
- public static String createTempQrCode(String access_token, String scene_str) {
- String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + access_token;
- Map<String, Object> data = new HashMap<>();
- data.put("expire_seconds", 604800);
- data.put("action_name", "QR_STR_SCENE");
- Map<String, Object> action_info = new HashMap<>();
- Map<String, Object> scene = new HashMap<>();
- scene.put("scene_str", scene_str);
- action_info.put("scene", scene);
- data.put("action_info", action_info);
- String json = HttpUtil.createPost(url)
- .header("Content-Type", "application/json")
- .body(JSONUtil.toJsonStr(data))
- .execute().body();
- System.out.println("json = " + json);
- String qrcode = (String) JSONUtil.getByPath(JSONUtil.parse(json), "ticket");
- return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + qrcode;
- }
-
-
-
- public static String getAccessToken() {
- accessToken = getNewAccessToken();
- return accessToken;
- }
-
-
- public static String getNewAccessToken() {
- String access_token = "";
- String grant_type = "client_credential";//获取access_token填写client_credential
- String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grant_type + "&appid=" + appId + "&secret=" + secret;
- try {
- URL urlGet = new URL(url);
- HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
- http.setRequestMethod("GET"); // 必须是get方式请求
- http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- http.setDoOutput(true);
- http.setDoInput(true);
- System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
- System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
- http.connect();
- InputStream is = http.getInputStream();
- int size = is.available();
- byte[] jsonBytes = new byte[size];
- is.read(jsonBytes);
- String message = new String(jsonBytes, "UTF-8");
- JSONObject demoJson = JSONObject.parseObject(message);
- System.out.println("JSON字符串:" + demoJson);
- access_token = demoJson.getString("access_token");
- is.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return access_token;
- }
-
-
-
-
公众号配置
java提供消息接收接口代码,有两个,一个get(公众平台网址验证的时候用),一个post(消息事件触发时用)
- /*
- * @param signature 微信加密签名,signature结合了开发者填写的 token 参数和请求中的 timestamp 参数、nonce参数。
- * @param timestamp 时间戳
- * @param nonce 这是个随机数
- * @param echostr 随机字符串,验证成功后原样返回
- */
- @GetMapping("/wx/event")
- public void get(@RequestParam(required = false) String signature,
- @RequestParam(required = false) String timestamp,
- @RequestParam(required = false) String nonce,
- @RequestParam(required = false) String echostr,
- HttpServletResponse response) throws IOException {
- System.out.println("接受事件===" + echostr);
- response.setCharacterEncoding("UTF-8");
- response.getWriter().write(echostr);
- response.getWriter().flush();
- response.getWriter().close();
- }
-
- //处理微信推送事件
- @PostMapping("/wx/event")
- public void post(final HttpServletRequest request, HttpServletResponse response) {
-
- System.out.println("接受事件");
- try {
- // 微信加密签名
- final String signature = request.getParameter("signature");
- // 时间戳
- final String timestamp = request.getParameter("timestamp");
- // 随机数
- final String nonce = request.getParameter("nonce");
- // 随机字符串
- final String echostr = request.getParameter("echostr");
- //将xml文件转成易处理的map(下方贴出)
- final Map<String, String> map = oConvertUtils.parseXml(request);
- //开发者微信号
- final String toUserName = map.get("ToUserName");
- //OpenId
- final String fromUserName = map.get("FromUserName");
- //消息创建时间 (整型)
- final String createTime = map.get("CreateTime");
- //消息类型,event
- final String msgType = map.get("MsgType");
- //事件类型
- final String event = map.get("Event");
-
- String scene_str = "";
- String msg = "";
- if ("event".equals(msgType)) {
- if (event.equals("subscribe")) {
- final String ticket = map.get("Ticket");
- if (ticket != null) {
- scene_str = map.get("EventKey").replace("qrscene_", "");
- }
- msg = getXmlReturnMsg(fromUserName, toUserName, (new Date()).getTime(), "欢迎您使用量子文档");
- }
- //注:事件类型为SCAN即已关注
- else if (event.equals("SCAN")) {
- final String ticket = map.get("Ticket");
- if (ticket != null) {
- scene_str = map.get("EventKey");
- }
- msg = getXmlReturnMsg(fromUserName, toUserName, (new Date()).getTime(), "您刚刚扫码登录了量子文档");
-
- }
- }
- System.out.println("event:" + event);
- System.out.println("场景值:" + scene_str);
- System.out.println("openId:" + fromUserName);
- System.out.println("ToUserName:" + toUserName);
-
- // 如果scene_str 不为空代表用户已经扫描并且关注了公众号
- if (oConvertUtils.isNotEmpty(scene_str)) {
- QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("open_id", fromUserName);
- SysUser sysUser = sysUserService.getOne(queryWrapper, false);
- if (sysUser == null) {
- sysUser = new SysUser();
- sysUser.setOpenId(fromUserName);
- sysUser.setUsername(fromUserName);
- sysUser.setRealname(null);
- String salt = oConvertUtils.randomGen(8);
- String passwordEncode = PasswordUtil.encrypt(fromUserName, salt, salt);
- sysUser.setSalt(salt);
- sysUser.setMemberLevelId("1");
- sysUser.setPassword(passwordEncode);
- sysUser.setStatus(1);
- sysUser.setDelFlag(CommonConstant.DEL_FLAG_0);
- sysUserService.save(sysUser);
- LzMessage message = new LzMessage();
- message.setMsgDate(new Date());
- message.setContent("欢迎您使用量子文档");
- message.setFileId(null);
- message.setIsRead(0);
- message.setDelFlag(0);
- message.setMsgType(3);
- message.setFromUserId("001");
- message.setFromUserName("小量子");
- message.setToUserId(sysUser.getId());
- lzMessageService.save(message);
- }
- // 将微信公众号用户ID缓存到redis中,标记用户已经扫码完成,执行登录逻辑。
- redisUtil.set(scene_str, fromUserName, 60);
- }
- System.out.println("打印消息体=========");
- System.out.println(msg);
- System.out.println("=========");
-
- response.setCharacterEncoding("UTF-8");
- PrintWriter out = response.getWriter();
- out.print(msg);
- out.flush();
- out.close();
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
vue前端轮询
- check() {
- if (this.loginType!='wx') return false;
- checkScanState(this.token).then((res) => {
- console.log(res);
- console.log("check....");
- if (res.data.success == true) {
- sessionStorage.setItem('token', res.data.result.token)
- sessionStorage.setItem('userId', res.data.result.userInfo.id)
- sessionStorage.setItem('userName', res.data.result.userInfo.username)
- sessionStorage.setItem('realname', res.data.result.userInfo.realname)
- sessionStorage.setItem('sex', res.data.result.userInfo.sex)
- sessionStorage.setItem('memberLevelName', res.data.result.memberLevel.name)
- sessionStorage.setItem('maxFileCount', res.data.result.memberLevel.maxFileCount)
- this.loginType = "";
- if (objToStr(res.data.result.userInfo.realname) == "") {
- this.$showInputBox({
- caption: "输入您的姓名",
- inputValue: '',
- callback: (data) => {
- updateRealname(res.data.result.userInfo.id, data).then((res) => {
- sessionStorage.setItem('realname', data)
- this.$closeInputBox();
- })
- }
- })
- }
- this.$router.push({
- path: '/person' ,
- })
- } else {
- setTimeout(() => {
- this.check();
- }, 1000);
- }
- })
- },
后端接受前端查状态的轮询请求
- @ApiOperation("检查扫码状态")
- @GetMapping("/checkScanState")
- public Result<JSONObject> wechatLogin(@RequestParam(name = "scene_str", required = true) String sceneStr) {
- Result<JSONObject> result = new Result<JSONObject>();
- Object openId = redisUtil.get(sceneStr);
- if (openId == null) {
- result.error500("未登入");
- return result;
- }
-
- QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("open_id", openId);
- SysUser sysUser = sysUserService.getOne(queryWrapper, false);
- if (sysUser != null) {
-
- String syspassword = sysUser.getPassword();
- String username = sysUser.getUsername();
- // 生成token
- String token = JwtUtil.sign(username, syspassword);
- redisUtil.del(CommonConstant.PREFIX_USER_TOKEN + token);
- //清空用户登录Shiro权限缓存
- redisUtil.del(CommonConstant.PREFIX_USER_SHIRO_CACHE + sysUser.getId());
- //清空用户的缓存信息(包括部门信息),例如sys:cache:user::<username>
- redisUtil.del(String.format("%s::%s", CacheConstant.SYS_USERS_CACHE, sysUser.getUsername()));
-
- result = sysUserService.checkUserIsEffective(sysUser);
- if(!result.isSuccess()) {
- return result;
- }
- //用户信息
- userInfo(sysUser, result);
- //添加日志
- sysBaseAPI.addLog("用户名: " + sysUser.getUsername() + ",登录成功!", CommonConstant.LOG_TYPE_1, null);
- }
- return result;
- }
-
-
-
- /**
- * 用户信息
- *
- * @param sysUser
- * @param result
- * @return
- */
- private Result<JSONObject> userInfo(SysUser sysUser, Result<JSONObject> result) {
- String syspassword = sysUser.getPassword();
- String username = sysUser.getUsername();
- // 生成token
- String token = JwtUtil.sign(username, syspassword);
- // 设置token缓存有效时间
- redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
- redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME*2 / 1000);
-
- // 获取用户部门信息
- JSONObject obj = new JSONObject();
- List<SysDepart> departs = sysDepartService.queryUserDeparts(sysUser.getId());
- obj.put("departs", departs);
- if (departs == null || departs.size() == 0) {
- obj.put("multi_depart", 0);
- } else if (departs.size() == 1) {
- sysUserService.updateUserDepart(username, departs.get(0).getOrgCode());
- obj.put("multi_depart", 1);
- } else {
- obj.put("multi_depart", 2);
- }
- obj.put("token", token);
- obj.put("userInfo", sysUser);
- obj.put("sysAllDictItems", sysDictService.queryAllDictItems());
- obj.put("memberLevel", lzMemberLevelService.getById(sysUser.getMemberLevelId()));
- result.setResult(obj);
- result.success("登录成功");
- return result;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。