salt盐的操作
salt生成工具类
public class SaltUtils {
/**
* 生成salt的静态方法
* @param n
* @return
*/
public static String getSalt(int n){
char[] chars= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890!@#$%^&*()".toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
char c = chars[new Random().nextInt(chars.length)];
sb.append(c);
}
return sb.toString();
}
}
工具类在代码中的使用:
String salt = SaltUtils.getSalt(8);
Md5Hash md5Hash = new Md5Hash(user.getPassword(), salt,1024);
JWT 实现shiro无状态认证
jwt其实就是令牌
jwt结构:
header. payload . signature
header头部
payload载荷(可以存储很多信息,eg.签发人,创建时间,失效时间,唯一标识)
signature签名
使用步骤:
引入maven依赖:
<!--引入jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
生成token
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND, 90);
//生成令牌
String token = JWT.create()
.withClaim("username", "张三")//设置自定义用户名
.withExpiresAt(instance.getTime())//设置过期时间
.sign(Algorithm.HMAC256("token!Q2W#E$RW"));//设置签名 保密 复杂
//输出令牌
System.out.println(token);
token令牌解析:
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("token!Q2W#E$RW")).build();
DecodedJWT decodedJWT = jwtVerifier.verify(token);
System.out.println("用户名: " + decodedJWT.getClaim("username").asString()); 、// 存的是时候是什么类型,取得时候就是什么类型,否则取不到值。
System.out.println("过期时间: "+decodedJWT.getExpiresAt());
封装token工具类
public class JWTUtils {
private static String TOKEN = "token!Q@W3e4r";
/**
* 生成token
* @param map //传入payload
* @return 返回token
*/
public static String getToken(Map<String,String> map){
JWTCreator.Builder builder = JWT.create();
map.forEach((k,v)->{
builder.withClaim(k,v);
});
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND,7);
builder.withExpiresAt(instance.getTime());
return builder.sign(Algorithm.HMAC256(TOKEN));
}
/**
* 验证token
* @param token
* @return
*/
public static void verify(String token){
JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token); // 如果验证通过,则不会把报错,否则会报错
}
/**
* 获取token中payload
* @param token
* @return
*/
public static DecodedJWT getToken(String token){
return JWT.require(Algorithm.HMAC256(TOKEN)).build().verify(token);
}
}
JWT在springboot的使用:
用拦截器拦截token:
public class JWTInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
Map<String,Object> map = new HashMap<>();
try {
JWTUtils.verify(token);
return true;
} catch (TokenExpiredException e) {
map.put("state", false);
map.put("msg", "Token已经过期!!!");
} catch (SignatureVerificationException e){
map.put("state", false);
map.put("msg", "签名错误!!!");
} catch (AlgorithmMismatchException e){
map.put("state", false);
map.put("msg", "加密算法不匹配!!!");
} catch (Exception e) {
e.printStackTrace();
map.put("state", false);
map.put("msg", "无效token~~");
}
String json = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtTokenInterceptor()).
excludePathPatterns("/user/**") // 放行
.addPathPatterns("/**"); // 拦截除了"/user/**的所有请求路径
}
}
JWT+shiro