日志
1、定义日志接口
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String type() default "";
String module() default "";
String content() default "";
}
2、定义日志切面类
@Aspect
@Component
public class LogAspect {
@Autowired
private LogService logService;
@Pointcut("@annotation(com.nudt.annotation.LogAnnotation)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveLog(point, (int) time);
return result;
}
private void saveLog(ProceedingJoinPoint joinPoint, int time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Log log = new Log();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
if (logAnnotation != null) {
//注解上的描述
log.setOperation(logAnnotation.content());
}
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.setMethod(className + "." + methodName + "()");
//请求的参数
Object[] args = joinPoint.getArgs();
try {
String params = new Gson().toJson(args[0]);
log.setParams(params);
} catch (Exception e) {
}
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
//获取登录名
String loginName = (String) session.getAttribute("loginName");
//获取客户端ip
String clientIp = IPUtil.getClientIp();
//获取服务端ip
String serverIp = IPUtil.getServerIp();
}
}
3、使用
@GetMapping
@LogAnnotation(module="登录",content="用户登录",type="1")
public String login(){
}
验证
1、定义验证接口
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validate {
String value() default "";
}
2、定义验证切面类
@Aspect
@Component
public class ValidateAspect {
@Pointcut("@annotation(com.nudt.annotation.Validate)")
public void validatePointCut() {
}
@Before("validatePointCut()")
public void before(JoinPoint joinPoint) throws Exception{
int status = IPUtil.getStatus();
if(status==0){
throw new ValidationException("未登录");
}
if(status==1){
throw new ValidationException("无权限");
}
}
}
3、使用
@GetMapping
@Validate
public String del(){
}
工具类:获取服务器和客户端ip,以及在session中获取信息
public class IPUtil {
private static final Logger log = LoggerFactory.getLogger(IPUtil.class);
//获取服务器ip
public static String getServerIp() {
try{
InetAddress localhost = InetAddress.getLocalHost();
return localhost.getHostAddress();
}catch(UnknownHostException e){
throw new RuntimeException(e);
}
}
//获取客户端ip
public static String getClientIp() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getHeader("x-forwarded-for");
log.info("x-forwarded-for ip:{}",ip);
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
log.info("Proxy-Client-IP ip:{}",ip);
}
if (StringUtils.isBlank(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
log.info("WL-Proxy-Client-IP ip:{}",ip);
}
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
log.info("HTTP_CLIENT_IP ip:{}",ip);
}
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
log.info("HTTP_X_FORWARDED_FOR ip:{}",ip);
}
if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
log.info("remote ip:{}",ip);
}
if(StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip) && StringUtils.contains(ip,",")){
//多次反向代理后会有多个ip值,第一个为真实ip
ip = StringUtils.substringBefore(ip,",");
}
String tempIp = null;
if(StringUtils.isNotBlank(ip) && !"unknown".equalsIgnoreCase(ip) && StringUtils.contains(ip,",")){
String[] ips = StringUtils.split(ip, ",");
for(String ip1:ips){
if(!isInnerIp(ip1.trim())){
tempIp = ip1.trim();
break;
}
//如果多ip都是内网ip,则取第一个ip
if(null == tempIp){
tempIp = ips[0].trim();
}
ip = tempIp;
}
}
if(ip !=null && ip.contains("unknown")){
ip = ip.replaceAll("unknown","");
ip = ip.trim();
}
//处理localhost
if(StringUtils.isBlank(ip) || !"unknown".equalsIgnoreCase(ip) || StringUtils.split(ip,",").length!=4){
try{
InetAddress inetAddress = InetAddress.getLocalHost();
ip = inetAddress.getHostAddress();
log.info("getHostAddress ip:{}",ip);
}catch(UnknownHostException e){
throw new RuntimeException(e);
}
}
return ip;
}
private static boolean isInnerIp(String ipAddress) {
boolean isInnerIp;
long ipNum = getIpNum(ipAddress);
// 私有ip:A类 10.0.0.0~10.255.255.255
// B类 172.16.0.0~172.31.255.255
// C类 192.168.0.0~192.168.255.255
long aBegin = getIpNum("10.0.0.0");
long aEnd = getIpNum("10.255.255.255");
long bBegin = getIpNum("172.16.0.0");
long bEnd = getIpNum("172.31.255.255");
long cBegin = getIpNum("192.168.0.0");
long cEnd = getIpNum("192.168.255.255");
isInnerIp = isInner(ipNum,aBegin,aEnd) || isInner(ipNum,bBegin,bEnd) || isInner(ipNum,cBegin,cEnd);
return isInnerIp;
}
private static boolean isInner(long ipNum, long begin, long end){
return (ipNum >= begin) && (ipNum <= end);
}
private static long getIpNum(String ipAddress) {
String[] ips = StringUtils.split(ipAddress,",");
long a = Integer.parseInt(ips[0]);
long b = Integer.parseInt(ips[1]);
long c = Integer.parseInt(ips[2]);
long d = Integer.parseInt(ips[3]);
return a*256*256*256 + b*256*256 + c*256 + d;
}
public static int getStatus() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
//获取登录名
String token = (String) session.getAttribute("token");
Map<String, String> map = JwtUtil.parseJWT(token);
String status = map.get("type");
if(status.equals("0")){
return 0;
}
if(status.equals("1")){
return 1;
}
return 2;
}
}
工具类:jwt相关
public class JwtUtil {
//设置过期时间
private static final long EXPIRE_TIME = 240 * 60 * 1000;
//token秘钥
private static final String TOKEN_SECRET = "f26e587c28064d0e855e72c0a6a0e618";
public static String sign(String username, String type) {
String token = "";
try {
//过期时间
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
//秘钥及加密算法
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
//设置头部信息
Map<String, Object> header = new HashMap<>(2);
header.put("typ", "JWT");
header.put("alg", "HS256");
//携带username,password信息,生成签名
return JWT.create()
.withHeader(header)
.withClaim("loginName", username)
.withClaim("type", type)
.withExpiresAt(date)
.sign(algorithm);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static boolean verify(String token){
/**
* @desc 验证token,通过返回true
* @params [token]需要校验的串
**/
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
public static Map<String, String> parseJWT(String token){
/**
* @desc 解密token,返回一个map
* @params [token]需要校验的串
**/
DecodedJWT decodeToken = JWT.decode(token);
Map<String, String> map = new HashMap<>();
map.put("loginName",decodeToken.getClaim("loginName").asString());
map.put("type",decodeToken.getClaim("type").asString());
return map;
}
public static boolean isJwtExpired(String token){
/**
* @desc 判断token是否过期
* @author lj
*/
try {
DecodedJWT decodeToken = JWT.decode(token);
return decodeToken.getExpiresAt().before(new Date());
} catch(Exception e){
return true;
}
}
public static void main(String[] args) {
String username ="zhangsan";
String password = "123";
String token = sign(username,password);
System.out.println(token);
boolean b = verify(token);
System.out.println(b);
}
引入依赖
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>