效果图:
语言:JAVA
框架:SpringBoot
说明:
无需其它配置,按下面参考类即可实现接口返回ID变为随机密文,对业务无侵入
建议:
加密的KEY最好是用户登录成功之后再生成一个随机的KEY,安全性更高
实现代码:
/** 注解 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = IdHashSerializer.class)
@JsonDeserialize(using = IdHashDeserializer.class)
public @interface IdHash {
}
/** 加密类 **/
@Slf4j
public class IdHashSerializer extends JsonSerializer<Long> {
private HttpServletRequest request;
public IdHashSerializer(HttpServletRequest request) {
// Spring会自动注入
this.request = request;
}
@Override
public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if(value == null) return;
Object secretKey = request.getAttribute("D-Secret-Key"); //// 全局KEY 或 用户登录成功生成随机KEY
if(secretKey == null) {
gen.writeNumber(value);
return;
}
try {
////// 加密算法参考
gen.writeString(AesUtils.urlEncrypt(value.toString(), secretKey.toString()));
} catch (Exception e) {
log.warn("[idhash] serialize fail. value: {}, uid: {}", value, request.getAttribute("D-User-Id"));
throw new KnownException("90001", "无效的请求");
}
}
}
/** 解密类 **/
@Slf4j
public class IdHashDeserializer extends JsonDeserializer<Long> {
private HttpServletRequest request;
public IdHashDeserializer(HttpServletRequest request) {
this.request = request;
}
@Override
public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getText();
if(StringUtils.isEmpty(value)) {
return null;
}
Object secretKey = request.getAttribute("D-Secret-Key"); //// 全局KEY 或 用户登录成功生成随机KEY
if(secretKey != null) {
try {
return Long.parseLong(AesUtils.urlDecrypt(value, secretKey.toString()));
} catch (Exception e) {
log.warn("[idhash] deserialize fail. value: {}, uid: {}", value, request.getAttribute("D-User-Id"));
throw new KnownException("90002", "无效的请求,请刷新页面后重试");
}
}
return Long.parseLong(value);
}
}
使用示例:
@Getter
@Setter
@Schema(description = "保存-菜单")
public class SaveMenuDto {
@IdHash/** 注解 **/
@Schema(description = "菜单ID")
private Long id;
@IdHash/** 注解 **/
@Schema(description = "上级菜单ID")
@JsonSetter(nulls = Nulls.SKIP)
private Long pid = 0L;
...
}
@Getter
@Setter
public class QueryTreeVo implements BaseVo {
@IdHash/** 注解 **/
private Long id;
private String title;
private Integer status;
private Boolean leaf = true;
}