不可不学系列(其二): Token认证机制让你的Web项目插入梦想的翅膀

    科技2022-07-21  108

    文章目录

    Token认证机制Token的优势生成TokenToken示例说说心里话

    Token认证机制

    Token的优势

    可实现多种客户端的统一会话管理降低与其业务系统的耦合很容易加入第三方认证的支持

    生成Token

    服务器端 : 按规则生成token信息缓存在redis中, 同时返回给客户端

    客户端: 请求登录成功保存token, 并附加在下次请求的http信息头中, 以供服务器验证

    置换Token

    设置定期刷新会话, 防止被恶意盗取

    Token数据结构

    客户端标识-USERCODE - USERID -CREATIONDATE-RONDEM(6位)

    Token示例

    TokenService @Service public class TokenServiceImpl implements TokenService{ @Resource private RedisAPI redisAPI; /** * token: 客户端标识-USERCODE - USERID -CREATIONDATE-RONDEM(6位) * @param userAgent * @param admin * @return */ @Override public String generateToken(String userAgent, WebAdmin admin) { StringBuilder sb = new StringBuilder(); UserAgent agent = UserAgent.parseUserAgentString(userAgent); //移动设备 if(agent.getOperatingSystem().isMobileDevice()) { sb.append("MOBILE-"); } else sb.append("PC-"); sb.append(MD5Util.getMD5(admin.getLoginCode(), 16)).append("-"); sb.append(admin.getId().toString()).append("-"); sb.append(new SimpleDateFormat("yyyyMMddHHmmsss").format(new Date())).append("-"); sb.append(MD5Util.getMD5(userAgent, 6)); return sb.toString(); } /** * 需要针对不同的客户端 需要不同的过期处理 * @param token * @param admin */ @Override public void save(String token, WebAdmin admin) { if(token.startsWith("PC-")) { redisAPI.set(token, JSONObject.toJSONString(admin), 2 * 60 * 60); } else { //移动端不需要过期 redisAPI.set(token, JSONObject.toJSONString(admin)); } } @Override public boolean validate(String userAgent, String token) { if(!redisAPI.keyExist(token)) { return false; } String md5Agent = token.split("-")[4]; //判断是不是同一个浏览器 if(!md5Agent.equals(MD5Util.getMD5(userAgent, 6))) { return false; } //不需要考虑过期时间 一方面如果是pc端过期 redis会直接清理 如果是移动端也不用考虑 return true; } }

    注: 需要引入1个依赖: 至于redis和MD5,你使用token肯定是引入了,这里就不赘述了

    <dependency> <groupId>nl.bitwalker</groupId> <artifactId>UserAgentUtils</artifactId> <version>1.2.4</version> </dependency>

    验证Token

    客户端: 将token附加到请求的header中

    服务端: 从header取出token, 将其和redis中key-value进行比对

    代码在validate方法中

    删除Token

    直接手动调用redis的del的方法即可

    重置Token

    这个场景是, 用户每次请求业务时,都应该校验其token的有效期, 如果约定时间有效(一般是半个小时) 那么你可以访问, 如果无效那么 我需要置换token 具体细节如下

    //保护期30分钟 private long protectedTime = 30 * 60 * 1000; //延迟 private int delayTime = 2 * 60; @Override public String reload(String userAgent, String token) throws Exception { //1验证token是否有效 if (!redisAPI.keyExist(token)) { throw new Exception("token 无效!"); } //2.是否到了置换时间 String genDateStr = token.split("-")[3]; Date genDate = new SimpleDateFormat("yyyyMMddHHmmsss").parse(genDateStr); //经过的时间 long pass = Calendar.getInstance().getTimeInMillis() - genDate.getTime(); //判断是否在保护期之内 if(pass < protectedTime) { throw new Exception("token置换保护期, 无法置换! 剩余" + (protectedTime - pass ) / 1000); } //生成新的tokne WebAdmin admin = JSONObject.parseObject(redisAPI.get(token), WebAdmin.class); String newToken = generateToken(userAgent, admin); //3.老的token 延迟2分钟过期 redisAPI.set(token, redisAPI.get(token), delayTime); //4.新的token保存 save(newToken, admin); return newToken; }

    一般置换Token是放在定时任务中

    说说心里话

    最近又到了秋招的环节了, 笔者作为一名即将步入职场的新盆友, 正在疯狂吸收"全(栈)站"的知识, 虽然有些疲倦 但是每次掌握一个技能然后分享给大家这个阶段还是挺快乐的, 希望我的童鞋们多多捧场 让我更有信心更新下去, I need You!

    Processed: 0.015, SQL: 8