3.2、token存放客户端
还有一种方案,是将token存放客户端,这种方案就是服务端根据规则对数据进行加密生成一个签名串nosql数据库是什么的缩写xff0c;这个签名串就是我们所说的token,最后返回给前端。
因为加密的操作都是在服务端完成的,因此密钥的阿飘是什么意思管理非常重要,不能泄露rediscover出去,不然很容易被黑客解密出来存储容量单位。
最典型的应用就是JW缓存清理T!nosql怎么读;
JWT安全 是由三段信息构成的apicf0c;将这三段信息文本用.
链接一起就构成了JWT
字符串。就像这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
如何实现呢?首先我们需要添加一个jwt
依赖包。
<!-- jwt支持 --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
然后,创建一个用户信息类,将会通过加密存放在token
中
@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class UserToken implements Serializable { private static final long serialVersionUID = 1L; /** * 用户ID */ private String userId; /** * 用户登录账户 */ private String userNo; /** * 用户中文名 */ private String userName; }
接着nosql与mysql的区别,创建一个JwtTokenUtil
工具类,用于创建token
、验证token
public class JwtTokenUtil { //定义token返回头部 public static final String AUTH_HEADER_KEY = "Authorization"; //token前缀 public static final String TOKEN_PREFIX = "Bearer "; //签名密钥 public static final String KEY = "q3t6w9z$C&F)J@NcQfTjWnZr4u7x"; //有效期默认为 2hour public static final Long EXPIRATION_TIME = 1000L*60*60*2; /** * 创建TOKEN * @param content * @return */ public static String createToken(String content){ return TOKEN_PREFIX + JWT.create() .withSubject(content) .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) .sign(Algorithm.HMAC512(KEY)); } /** * 验证token * @param token */ public static String verifyToken(String token) throws Exception { try { return JWT.require(Algorithm.HMAC512(KEY)) .build() .verify(token.replace(TOKEN_PREFIX, "")) .getSubject(); } catch (TokenExpiredException e){ throw new Exception("token已失效,请重新登录",e); } catch (JWTVerificationException e) { throw new Exception("token验证失败!",e); } } }
同时编写配置类,允许跨域,并且创NOSQL建一个权限拦截器前端开发前景怎么样啊
@Slf4j @Configuration public class GlobalWebMvcConfig implements WebMvcConfigurer { /** * 重写父类提供的跨域请求处理的接口 * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { // 添加映射路径 registry.addMapping("/**") // 放行哪些原始域 .allowedOrigins("*") // 是否发送Cookie信息 .allowCredentials(true) // 放行哪些原始域(请求方式) .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS", "HEAD") // 放行哪些原始域(头部信息) .allowedHeaders("*") // 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息) .exposedHeaders("Server","Content-Length", "Authorization", "Access-Token", "Access-Control-Allow-Origin","Access-Control-Allow-Credentials"); } /** * 添加拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { //添加权限拦截器 registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**"); } }
使用AuthenticationInterceptor
拦截缓存视频怎样转入相册器对接口参数进行验证
@Slf4j public class AuthenticationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 从http请求头中取出token final String token = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY); //如果不是映射到方法,直接通过 if(!(handler instanceof HandlerMethod)){ return true; } //如果是方法探测,直接通过 if (HttpMethod.OPTIONS.equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); return true; } //如果方法有JwtIgnore注解,直接通过 HandlerMethod handlerMethod = (HandlerMethod) handler; Method method=handlerMethod.getMethod(); if (method.isAnnotationPresent(JwtIgnore.class)) { JwtIgnore jwtIgnore = method.getAnnotation(JwtIgnore.class); if(jwtIgnore.value()){ return true; } } LocalAssert.isStringEmpty(token, "token为空,鉴权失败!"); //验证,并获取token内部信息 String userToken = JwtTokenUtil.verifyToken(token); //将token放入本地缓存 WebContextUtil.setUserToken(userToken); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //方法结束后,移除缓存的token WebContextUtil.removeUserToken(); } }
最后javaeeff0c;在controller
层用户登录之后,创建一个token
,存放在头部即可
/** * 登录 * @param userDto * @return */ @JwtIgnore @RequestMapping(value = "/login", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) public UserVo login(@RequestBody UserDto userDto, HttpServletResponse response){ //...参数合法性验证 //从数据库获取用户信息 User dbUser = userService.selectByUserNo(userDto.getUserNo); //....用户、密码验证 //创建token,并将token放在响应头 UserToken userToken = new UserToken(); BeanUtils.copyProperties(dbUser,userToken); String token = JwtTokenUtil.createToken(JSONObject.toJSONString(userToken)); response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, token); //定义返回结果 UserVo result = new UserVo(); BeanUtils.copyProperties(dbUser,result); return result; }
到这里基javaee本就完成了!
其中Authenticajava怎么读tionInterceptor
中用到的JwtIgnore
是一个注解,用于不需要验证token
的方法上,例如验证码的获取等等。
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface JwtIgnore { boolean value() default true; }
而WebContextUtil
是一个线程缓存工具类,其他接口通过这存储处理国家秘密的计算机信息个方法即可从token
中获取用户信息。
public class WebContextUtil { //本地线程缓存token private static ThreadLocal<String> local = new ThreadLocal<>(); /** * 设置token信息 * @param content */ public static void setUserToken(String content){ removeUserToken(); local.set(content); } /** * 获取token信息 * @return */ public static UserToken getUserToken(){ if(local.get() != null){ UserToken userToken = JSONObject.parseObject(local.get() , UserToken.class); return userToken; } return null; } /** * 移除token信息 * @return */ public static void removeUserToken(){ if(local.get() != null){ local.remove(); } } }
对应用系统而言,重点在于java模拟器token
的验证,可以将拦截器方法封装成一个公共的jar
包,然后各个应用系统引用即可!
和上面阿飘介绍的token
存储到redis
方案类似前端开发java培训f0c;不同点在于:一个将用户数据存储到redis阿飘是什么意思
ÿnosql数据库的特点0c;另一个是采用加密算法存储到客户端进行传输。
四、小结java
在实际的使用过程中ÿjava语言0c;我个人更加倾向于采用jwt
方案,直接在服务端使用签名加密算法API生成一个token
ÿnosql全称0c;然后在客户端进行流转,天然支持分布式,但是要注意加密时用的密钥要安全管理。
而采用redis
方案存储的时候,你需要搭建高可用的集群环境,同时保证缓存数据不会失效等等,维护成本高!
在实际的实现上,每个公司玩法不一java样,有的安全性要求高,后端还会加上密钥环节进行安全验证,基本思缓存视频怎样转入本地视频路大同小异。
发表评论