wordpress调用外部数据库,南通seo招聘,如何制作简单网页,手机制作动画的appSpringBoot集成JWT首先我们搭建好SpringBoot框架#xff0c;SpringBoot环境准备就绪。接下来执行以下操作#xff1a;1.引入依赖引入JWT依赖,由于是基于Java#xff0c;所以需要的是java-jwt。dependencygroupIdcom.auth0/groupIdartifactIdSpringBoot环境准备就绪。接下来执行以下操作1.引入依赖引入JWT依赖,由于是基于Java所以需要的是java-jwt。dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion3.5.0/version
/dependency2.自定义注解在这一步我们在annotation包下定义一个用户需要登录才能进行其他接口访问等一系列操作的注解TokenRequired。Target({ElementType.METHOD, ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
public interface TokenRequired {boolean required() default true;
}Target旨意为我们自定义注解TokenRequired的作用目标因为我们本次注解的作用目标为方法层级因此使用 ElementType.METHOD。Retention旨意为我们自定义注解 TokenRequired的保留位置TokenRequired的保留位置被定义为RetentionPolicy.RUNTIME这种类型的注解将被JVM保留,他能在运行时被JVM或其他使用反射机制的代码所读取和使用。3.定义实体类在entity包中我们使用lombok简单自定义一个实体类User。Data
AllArgsConstructor
NoArgsConstructor
public class User {String Id;String username;String password;
}4.定义一个JWT工具类在这一步我们在util包下面创建一个JwtUtil工具类用于生成token和校验token。public class JwtUtil {//过期时间15分钟private static final long EXPIRE_TIME 15*60*1000;//生成签名,15分钟后过期public static String sign(String username,String userId,String password){//过期时间Date date new Date(System.currentTimeMillis() EXPIRE_TIME);//使用用户密码作为私钥进行加密Algorithm algorithm Algorithm.HMAC256(password);//设置头信息HashMapString, Object header new HashMap(2);header.put(typ, JWT);header.put(alg, HS256);//附带username和userID生成签名return JWT.create().withHeader(header).withClaim(userId,userId).withClaim(username,username).withExpiresAt(date).sign(algorithm);}//校验tokenpublic static boolean verity(String token,String password){try {Algorithm algorithm Algorithm.HMAC256(password);JWTVerifier verifier JWT.require(algorithm).build();verifier.verify(token);return true;} catch (IllegalArgumentException e) {return false;} catch (JWTVerificationException e) {return false;}}
}5.业务校验并生成token在service包下我们创建一个UserService并定义一个login方法用于做登录接口的业务层数据校验并调取JwtUtil中方法生成token。Service(UserService)
public class UserService {AutowiredUserMapper userMapper;public String login(String name, String password) {String token null;try {//校验用户是否存在User user userMapper.findByUsername(name);if(user null){ResultDTO.failure(new ResultError(UserError.EMP_IS_NULL_EXIT));}else{//检验用户密码是否正确if(!user.getPassword().equals(password)){ResultDTO.failure(new ResultError(UserError.PASSWORD_OR_NAME_IS_ERROR));}else {// 生成token将 user id 、userName保存到 token 里面token JwtUtil.sign(user.getUsername(),user.getId(),user.getPassword());}}} catch (Exception e) {e.printStackTrace();}return token;}
}Algorithm.HMAC256():使用HS256生成token,密钥则是用户的密码唯一密钥的话可以保存在服务端。withAudience()存入需要保存在token的信息这里我把用户ID存入token中。6.定义拦截器接下来我们需要写一个拦截器去获取token并验证token。 public class AuthenticationInterceptor implements HandlerInterceptor {AutowiredUserService userService;Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {// 从 http 请求头中取出 tokenString token httpServletRequest.getHeader(token);// 如果不是映射到方法直接通过if(!(object instanceof HandlerMethod)){return true;}HandlerMethod handlerMethod(HandlerMethod)object;Method methodhandlerMethod.getMethod();//检查有没有需要用户权限的注解if (method.isAnnotationPresent(TokenRequired.class)) {TokenRequired userLoginToken method.getAnnotation(TokenRequired.class);if (userLoginToken.required()) {// 执行认证if (token null) {throw new RuntimeException(无token请重新登录);}// 获取 token 中的 user idString userId;try {userId JWT.decode(token).getClaim(userId).asString();} catch (JWTDecodeException j) {throw new RuntimeException(401);}User user userService.findUserById(userId);if (user null) {throw new RuntimeException(用户不存在请重新登录);}// 验证 tokentry {if(!JwtUtil.verity(token,user.getPassword())){throw new RuntimeException(无效的令牌);}} catch (JWTVerificationException e) {throw new RuntimeException(401);}return true;}}return true;}Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}
}AuthenticationInterceptor拦截器实现了HandlerInterceptor接口的三个方法boolean preHandle ()预处理回调方法,实现处理器的预处理第三个参数为响应的处理器,自定义Controller返回值返回值为true会调用下一个拦截器或处理器或者接着执行postHandle()和afterCompletion()false表示流程中断不会继续调用其他的拦截器或处理器中断执行。2.void postHandle()后处理回调方法实现处理器的后处理DispatcherServlet进行视图返回渲染之前进行调用此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理modelAndView也可能为null。3.void afterCompletion():整个请求处理完毕回调方法,该方法也是需要当前对应的Interceptor的preHandle()的返回值为true时才会执行也就是在DispatcherServlet渲染了对应的视图之后执行。用于进行资源清理。该拦截器的执行流程为从 http 请求头中取出 token检查有没有需要用户权限的注解如果需要检验token是否为空如果token不为空查询用户信息并校验token校验通过则进行业务访问处理校验失败则返回token失效信息。7.配置拦截器在配置类上添加了注解Configuration标明了该类是一个配置类并且会将该类作为一个SpringBean添加到IOC容器内。Configuration
public class InterceptorConfig implements WebMvcConfigurer {Beanpublic AuthenticationInterceptor authenticationInterceptor() {return new AuthenticationInterceptor();}Overridepublic void addInterceptors(InterceptorRegistry registry) {// 将我们上步定义的实现了HandlerInterceptor接口的拦截器实例authenticationInterceptor添加InterceptorRegistration中并设置过滤规则所有请求都要经过authenticationInterceptor拦截。registry.addInterceptor(authenticationInterceptor()).addPathPatterns(/**);}
}WebMvcConfigurer接口是Spring内部的一种配置方式采用JavaBean的形式来代替传统的xml配置文件来实现基本的配置需要。InterceptorConfig内的addInterceptor需要一个实现HandlerInterceptor接口的拦截器实例addPathPatterns方法用于设置拦截器的过滤路径规则。在addInterceptors方法中我们将第6步定义的实现了HandlerInterceptor接口的拦截器实例authenticationInterceptor添加至InterceptorRegistration中并设置过滤路径。现在我们所有请求都要经过authenticationInterceptor的拦截,拦截器authenticationInterceptor通过preHandle方法的业务过滤判断是否有TokenRequired 来决定是否需要登录。8.定义接口方法并添加注解RestController
RequestMapping(user)
public class UserController {AutowiredUserService userService;/*** 用户登录* param user* return*/PostMapping(/login)public ResultDTO login( User user){String token userService.login(user.getUsername(), user.getPassword());if (token null) {return ResultDTO.failure(new ResultError(UserError.PASSWORD_OR_NAME_IS_ERROR));}MapString, String tokenMap new HashMap();tokenMap.put(token, token);return ResultDTO.success(tokenMap);}TokenRequiredGetMapping(/hello)public String getMessage(){return 你好哇我是小码仔;}
}
不加注解的话默认不验证登录接口一般是不验证的。所以我在getMessage()中加上了登录注解说明该接口必须登录获取token后在请求头中加上token并通过验证才可以访问。请求验证我在代码中对getMessage()添加了TokenRequired注解此刻访问该方法时必须要通过登录拿取到token值并在请求头中添加token才可以访问。我们现在做以下校验直接访问不在请求头里添加token如上图所示请求结果显示无token请重新登录2.访问登录接口获取token并在请求头中添加token信息此时访问成功3.15分钟后token失效我们再次在请求头中添加token信息访问此时token已失效返回无效的令牌。 总结回顾一下本次JWT使用的基本业务判断流程用户访问页面前端请求相关接口经过拦截器拦截器中从 http 请求头中取出 token检查该接口有没有TokenRequired注解如果没有直接放行如果有检验token是否为空如果token为空访问失败token不为空则查询用户信息并校验token校验通过则进行业务访问处理校验失败则返回token失效信息。不足之处本次集成只是做一个简单的JWT使用介绍没有实现token的过期刷新机制此种情况下用户每隔15分钟就需要重新登录一次如果在实际生产环境中使用可能会被用户打死因此实际开发中并不推荐。关于token的刷新机制将在下篇文章中为大家解读并附上源码。本次集成代码地址https://github.com/bailele1995/springboot-jjwt.git来源https://juejin.im/post/5ea27c5be51d4546c27bdf94?utm_sourcetuicoolutm_mediumreferral