1 所需依赖
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency>
2. 工具类
public class JwtUtil { private JwtUtil(){} // 创建jwt public static String createJwt(Object subject){ Long exp = System.currentTimeMillis() + ( 1 * 60 * 60 * 1000); JwtBuilder builder = Jwts.builder(); builder.setHeaderParam("typ","JWT") .setHeaderParam("alg", SignatureAlgorithm.HS256) .setSubject(JSON.toJSONString(subject)) // 放置数据 .setExpiration(new Date(exp)) .setId(UUID.randomUUID()+"") .setIssuer("system") .signWith(SignatureAlgorithm.HS256,encrypt("123456")); return builder.compact(); } // 解析jwt public static <T> T parseJwt(String jwt,Class<T> clazz){ JwtParser parser = Jwts.parser(); String subject = parser.setSigningKey(encrypt("123456")).parseClaimsJws(jwt).getBody().getSubject(); System.out.println(subject); return JSON.parseObject(subject,clazz); } // 解析jwt public static void parseJwt(String jwt){ JwtParser parser = Jwts.parser(); parser.setSigningKey(encrypt("123456")).parseClaimsJws(jwt).getBody().getSubject(); } private static Key encrypt(String key){ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(),"AES"); return secretKeySpec; } }
3.登录接口
@Override public Result<Map<String,Object>> login(User param) { QueryWrapper<User> wrapper = new QueryWrapper<>(); wrapper.eq("username",param.getUsername()); wrapper.eq("password",param.getPassword()); User user = this.baseMapper.selectOne(wrapper); if(user == null){ return Result.fail(20002,"用户名或密码错误"); } // 登录成功,将用户信息写入redis /*String key = "user:"+UUID.randomUUID()+""; user.setPassword(null); redisTemplate.opsForValue().set(key,user,60L, TimeUnit.MINUTES); */ // 产生jwt凭证 user.setPassword(null); String token = JwtUtil.createJwt(user); Map<String,Object> data = new HashMap<>(); data.put("token", token); return Result.success(data); } @Override public Result getUserInfoByToken(String token) { // 通过token从redis中获取登录用户信息 /*Object obj = redisTemplate.opsForValue().get(token); if(obj == null){ return Result.fail(20003,"登录凭证无效,请重新登录"); } log.debug("--------> obj: " + obj); log.debug("--------> obj to json: " + JSON.toJSONString(obj)); User user = JSON.parseObject(JSON.toJSONString(obj),User.class);*/ // 解析jwt, 解析失败则jwt无效,未登录 User user = null; try { user = JwtUtil.parseJwt(token, User.class); } catch (Exception e) { e.printStackTrace(); return Result.fail(20003,"登录凭证无效,请重新登录"); } Map<String,Object> data = new HashMap<>(); data.put("roles", Arrays.asList(user.getRoleId()+"")); data.put("avatar",user.getAvatar()); data.put("name",user.getUsername()); // 根据角色id查询菜单权限列表 List<Menu> menuList = menuService.getMenuTreeByRoleId(user.getRoleId()); data.put("menuList",menuList); return Result.success(data); }
客户端发一个人请求到网关里面 通过网关的拦截器做效验 拦截效验jwt有效性(判断授权状态 有没有验证通过 如果授权没通过就会要求你去授权 会要用户去登录) 然后带着用户名跟密码去找授权服务目前项目里授权服务暂时是用户服务找授权服务授权通过就会给你颁发一个jwt这么一个凭证就是那个token那个token是加密的然后再返回给前端前端下次再去访问具体的某一项信息的时候 比如说访问订单 就会携带token去找订单如果订单里面想去拿到用户信息他就会解密token 解密token有两种方式一种你可以找授权服务让它去帮你解密 这样解密就是其他的所有微服务都不关注他的逻辑好处就是不关注 坏处就是会导致授权服务压力会越大还一种方式就是你们自己解密 这个解密说白啦就是一个工具方法(产生jwt解析jwt) 我们直接写好后呢我们把它放在统一的公共的一个项目里面这样大家依赖一下就都可以用啦