根据请求头区分请求是pc端还是app端工具类 实现app和pc统一登录逻辑
package com.xiaokun.device_status.utils; import javax.servlet.http.HttpServletRequest; public class UserAgentUtil { public void index(HttpServletRequest request) { String ua = request.getHeader("User-Agent"); if (UserAgentUtil.checkAgentIsMobile(ua)) { System.out.println("移动端"); } else { System.out.println("PC端"); } } /** * 判断User-Agent 是不是来自于手机 * @param ua * @author Leemeea * @return */ public static boolean checkAgentIsMobile(String ua) { String[] deviceArray = new String[] { "android", "iPhone", "ipod", "ipad", "blackberry", "ucweb", "windows phone" }; if (ua == null) { return false; } ua = ua.toLowerCase(); for (String string : deviceArray) { if (ua.indexOf(string) > 0) { return true; } } return false; } }
登录接口逻辑
@Override public String findByLoginDto(LoginDto loginDto, HttpServletResponse response, HttpServletRequest request, String ip) { UserToken userToken = new UserToken(); String token = null; /**检查数据库用户是否存在*/ User user = loginMapper.getUser(loginDto.getAccountNumber(),loginDto.getPassword()); if (user == null) return null; byte[] data = user.getAccountNumber().getBytes(); byte[] signed = sign.sign(data); token = Base64Encoder.encode(signed); String userAgent = request.getHeader(HttpHeaders.USER_AGENT); /**标识是app端还是pc端*/ String flag = UserAgentUtil.checkAgentIsMobile(userAgent) ? "app" : "pc"; /**存进redis的对象*/ userToken.setUserId(user.getUserId()); userToken.setIp(ip); userToken.setToken(token+user.getAccountNumber()+flag); userToken.setAccountNumber(user.getAccountNumber()); userToken.setUserAgent(userAgent); String result = JSONObject.toJSON(userToken).toString(); //用户token的转字符串 /**第二次登录,刷新token,并删除之前的用户token 以登录的唯一账号+登录设备端 作为唯一key*/ if (redisTemplate.hasKey(user.getAccountNumber() + flag)) { redisTemplate.delete(user.getAccountNumber() + flag); redisTemplate.opsForValue().set(user.getAccountNumber() + flag,result,7, TimeUnit.DAYS); }else { redisTemplate.opsForValue().set(user.getAccountNumber() + flag,result,7, TimeUnit.DAYS); }
return userToken.getToken(); }
拦截器逻辑
@Override public void findUser(String token, String ip,String status) { Assert.notEmpty(token,"token为空,用户未登录"); /**切割token获得用户唯一key*/ String[] split = token.split("="); String accountNumber = split[split.length - 1]; //13129137992pc or13129137992app boolean flag; //标识redis里有没有那个用户的key // String userAgentFlag = UserAgentUtil.checkAgentIsMobile(status) ? "app":"pc"; //标识前端请求头是pc还是app flag = redisTemplate.hasKey(accountNumber); String s = ""; //redis里的用户对象字符串 if (flag) { s = redisTemplate.opsForValue().get(accountNumber).toString(); }else { throw new RuntimeException("用户登录凭证已失效,请重新登录"); } UserToken userToken = JSON.parseObject(s, UserToken.class); //redis里的用户token对象 String tokenIp = userToken.getIp(); String userAgent = userToken.getUserAgent(); if (!status.equals(userAgent) || !ip.equals(tokenIp)) { throw new RuntimeException("有人登录您的账号,请重新登录"); } /**再一次校验存在redis里的用户对象在数据库中查不查的到用户*/ User user = null; if (userToken != null) { user = loginMapper.getUserByUserId(userToken.getUserId()); } if (user == null) { throw new RuntimeException("用户不存在"); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)