diff --git a/pom.xml b/pom.xml
index 934ffc78eddc1957b847bb90ffd5e8dbf8a10db6..78b018c4c121ee9dd9383d8fe1b82eef55b77dc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,9 +46,10 @@
1.4.1
2.9.0
2.0.8
+ 3.11.1
6.6
7.10.1
- 3.11.1
+ 1.7.2
@@ -174,6 +175,12 @@
${redisson.version}
+
+ org.lionsoul
+ ip2region
+ ${ip2region.version}
+
+
diff --git a/youlai-admin/admin-api/src/main/java/com/youlai/admin/pojo/domain/LoginRecord.java b/youlai-admin/admin-api/src/main/java/com/youlai/admin/pojo/domain/LoginRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..2aba2188e56e5d2b5eeb660ed036d8ac5f720c6f
--- /dev/null
+++ b/youlai-admin/admin-api/src/main/java/com/youlai/admin/pojo/domain/LoginRecord.java
@@ -0,0 +1,30 @@
+package com.youlai.admin.pojo.domain;
+
+import lombok.Data;
+
+/**
+ * @author hxr
+ * @date 2021-03-09
+ */
+@Data
+public class LoginRecord {
+
+ private String _id;
+
+ private String description;
+
+ private String clientIP;
+
+ private long elapsedTime;
+
+ private Object message;
+
+ private String token;
+
+ private String username;
+
+ private String loginTime;
+
+ private String region;
+
+}
diff --git a/youlai-admin/admin-boot/pom.xml b/youlai-admin/admin-boot/pom.xml
index 1d278068317a8b17907c5c80ce8598b5dc68d7c5..c7a8b246e7bc4e358da7b9055ebb326bdd726518 100644
--- a/youlai-admin/admin-boot/pom.xml
+++ b/youlai-admin/admin-boot/pom.xml
@@ -77,7 +77,10 @@
spring-boot-starter-web
-
+
+ com.nimbusds
+ nimbus-jose-jwt
+
diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/constant/ESConstants.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/constant/ESConstants.java
index 7eaa506039b225b7e19df4d852ebf609aaee7c76..1d6416ed302113036304951037f2bb69d9253797 100644
--- a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/constant/ESConstants.java
+++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/constant/ESConstants.java
@@ -8,4 +8,7 @@ public interface ESConstants {
String INDEX_LOGIN_PREFIX = "youlai-auth-login-";
+
+ String INDEX_LOGIN_PATTERN = "youlai-auth-login-*";
+
}
diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/DashboardController.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/DashboardController.java
index 9d34dcb5d196470e56beac8b56fd3cd52ab46e27..b1d4ab8f5afa2eeec11d1f56d94544bd276d37f2 100644
--- a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/DashboardController.java
+++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/DashboardController.java
@@ -4,7 +4,7 @@ import cn.hutool.core.convert.Convert;
import com.youlai.admin.common.constant.ESConstants;
import com.youlai.common.elasticsearch.service.ElasticSearchService;
import com.youlai.common.result.Result;
-import com.youlai.common.web.util.IpUtils;
+import com.youlai.common.web.util.IPUtils;
import com.youlai.common.web.util.RequestUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -72,7 +72,7 @@ public class DashboardController {
// 当前用户统计
HttpServletRequest request = RequestUtils.getRequest();
- String clientIP = IpUtils.getIpAddr(request);
+ String clientIP = IPUtils.getClientIP(request);
boolQueryBuilder.must(QueryBuilders.termQuery("clientIP", clientIP));
Map myCountMap = elasticSearchService.dateHistogram(boolQueryBuilder, "date", DateHistogramInterval.days(1), indices);
@@ -97,4 +97,5 @@ public class DashboardController {
return Result.success(map);
}
+
}
diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/LoginRecordController.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/LoginRecordController.java
new file mode 100644
index 0000000000000000000000000000000000000000..98bec1597e5d9b388e5caef3630f31dc4dca1520
--- /dev/null
+++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/LoginRecordController.java
@@ -0,0 +1,92 @@
+package com.youlai.admin.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.youlai.admin.common.constant.ESConstants;
+import com.youlai.admin.pojo.domain.LoginRecord;
+import com.youlai.common.elasticsearch.service.ElasticSearchService;
+import com.youlai.common.result.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.elasticsearch.index.query.BoolQueryBuilder;
+import org.elasticsearch.index.query.QueryBuilders;
+import org.elasticsearch.index.query.RangeQueryBuilder;
+import org.elasticsearch.search.sort.FieldSortBuilder;
+import org.elasticsearch.search.sort.SortOrder;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * @author hxr
+ * @date 2021-03-09
+ */
+@Api(tags = "登录记录")
+@RestController
+@RequestMapping("/api.admin/v1/records/login")
+@Slf4j
+@AllArgsConstructor
+public class LoginRecordController {
+
+ ElasticSearchService elasticSearchService;
+
+
+
+ @ApiOperation(value = "列表分页", httpMethod = "GET")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "page", value = "页码", defaultValue = "1", paramType = "query", dataType = "Long"),
+ @ApiImplicitParam(name = "limit", value = "每页数量", defaultValue = "10", paramType = "query", dataType = "Long"),
+ @ApiImplicitParam(name = "startDate", value = "开始日期", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "endDate", value = "结束日期", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "clientIP", value = "客户端IP", paramType = "query", dataType = "String")
+ })
+ @GetMapping
+ public Result list(
+ Integer page,
+ Integer limit,
+ String startDate,
+ String endDate,
+ String clientIP
+ ) {
+
+ // 日期范围
+ RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("date");
+
+ if (StrUtil.isNotBlank(startDate)) {
+ rangeQueryBuilder.from(startDate);
+ }
+ if (StrUtil.isNotBlank(endDate)) {
+ rangeQueryBuilder.to(endDate);
+ }
+
+ BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(rangeQueryBuilder);
+
+ if (StrUtil.isNotBlank(clientIP)) {
+ queryBuilder.must(QueryBuilders.wildcardQuery("clientIP", "*" + clientIP + "*"));
+ }
+ // 总记录数
+ long count = elasticSearchService.count(queryBuilder, ESConstants.INDEX_LOGIN_PATTERN);
+
+ // 排序
+ FieldSortBuilder sortBuilder = new FieldSortBuilder("@timestamp").order(SortOrder.DESC);
+
+ // 分页数
+ List list = elasticSearchService.search(queryBuilder, sortBuilder, page, limit, LoginRecord.class, ESConstants.INDEX_LOGIN_PATTERN);
+ return Result.success(list, count);
+ }
+
+
+ @ApiOperation(value = "删除登录记录", httpMethod = "DELETE")
+ @ApiImplicitParam(name = "ids", value = "id集合", required = true, paramType = "query", dataType = "String")
+ @DeleteMapping("/{ids}")
+ public Result delete(@PathVariable String ids) {
+ return Result.judge(true);
+ }
+
+
+
+
+}
diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/TokenController.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/TokenController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f00b8b94c2c7a6047fe54a84e747040c7de73df7
--- /dev/null
+++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/TokenController.java
@@ -0,0 +1,57 @@
+package com.youlai.admin.controller;
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.nimbusds.jose.JWSObject;
+import com.youlai.common.constant.AuthConstants;
+import com.youlai.common.result.Result;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.util.Strings;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author hxr
+ * @date 2021-03-09
+ */
+
+@Api(tags = "令牌接口")
+@RestController
+@RequestMapping("/api.admin/v1/tokens")
+@Slf4j
+@AllArgsConstructor
+public class TokenController {
+
+ RedisTemplate redisTemplate;
+
+ @ApiOperation(value = "强制下线", httpMethod = "POST")
+ @ApiImplicitParam(name = "token", value = "访问令牌", required = true, paramType = "query", dataType = "String")
+ @PostMapping("/{token}/_invalid")
+ @SneakyThrows
+ public Result invalidToken(@PathVariable String token) {
+
+ token = token.replace(AuthConstants.AUTHORIZATION_PREFIX, Strings.EMPTY);
+ JWSObject jwsObject = JWSObject.parse(token);
+ String payload = jwsObject.getPayload().toString();
+
+ JSONObject jsonObject = JSONUtil.parseObj(payload);
+ long currentTimeSeconds = System.currentTimeMillis() / 1000;
+
+ String jti = jsonObject.getStr(AuthConstants.JWT_JTI); // JWT唯一标识
+ long exp = jsonObject.getLong(AuthConstants.JWT_EXP); // JWT过期时间戳
+
+ if (exp < currentTimeSeconds) { // token已过期,无需加入黑名单
+ return Result.success();
+ }
+ redisTemplate.opsForValue().set(AuthConstants.TOKEN_BLACKLIST_PREFIX + jti, null, (exp - currentTimeSeconds), TimeUnit.SECONDS);
+ return Result.success();
+ }
+
+}
diff --git a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/UserController.java b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/UserController.java
index d35949a48e10c6ff900ddda622c91610c97d8d1d..e58d0187a674a7b88214c2739ccc4eab7e5b2cba 100644
--- a/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/UserController.java
+++ b/youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/UserController.java
@@ -38,7 +38,6 @@ public class UserController extends BaseController {
private final ISysUserService iSysUserService;
private final ISysUserRoleService iSysUserRoleService;
- private final ISysRoleService iSysRoleService;
private final PasswordEncoder passwordEncoder;
private final ISysPermissionService iSysPermissionService;
diff --git a/youlai-admin/admin-boot/src/test/java/com/youlai/admin/ElasticSearchTests.java b/youlai-admin/admin-boot/src/test/java/com/youlai/admin/ElasticSearchTests.java
index b7e091a3cbb6ce830ebcd2b14aa18b42547bbe66..ec2780b8d107262545ac185b7a449dd6746daae4 100644
--- a/youlai-admin/admin-boot/src/test/java/com/youlai/admin/ElasticSearchTests.java
+++ b/youlai-admin/admin-boot/src/test/java/com/youlai/admin/ElasticSearchTests.java
@@ -1,16 +1,11 @@
package com.youlai.admin;
import com.youlai.common.elasticsearch.service.ElasticSearchService;
-import com.youlai.common.web.pojo.domain.LoginLog;
import lombok.extern.slf4j.Slf4j;
-import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
-import java.util.List;
-import java.util.Map;
-
@SpringBootTest
@Slf4j
public class ElasticSearchTests {
@@ -19,21 +14,8 @@ public class ElasticSearchTests {
private ElasticSearchService elasticSearchService;
@Test
- public void search() {
- List list = elasticSearchService.search(null, LoginLog.class, "youlai-auth-login-2021-03-06");
- System.out.println(list.toString());
- }
-
- @Test
- public void count(){
+ public void count() {
long count = elasticSearchService.count(null, "youlai-auth-login-2021-03-06");
log.info(String.valueOf(count));
}
-
-
- @Test
- public void group(){
- Map map = elasticSearchService.dateHistogram(null, "date",DateHistogramInterval.days(1),"youlai-auth-login-2021-03-07","youlai-auth-login-2021-03-08");
- log.info(map.toString());
- }
}
diff --git a/youlai-auth/src/main/java/com/youlai/auth/controller/LogoutController.java b/youlai-auth/src/main/java/com/youlai/auth/controller/LogoutController.java
index f1ae1e2fdfc92abd186cf0255460c5239dd712c3..df29e7737e15dfd74755aa2020a8e71ff7f04733 100644
--- a/youlai-auth/src/main/java/com/youlai/auth/controller/LogoutController.java
+++ b/youlai-auth/src/main/java/com/youlai/auth/controller/LogoutController.java
@@ -27,8 +27,8 @@ public class LogoutController {
@DeleteMapping("/logout")
public Result logout() {
JSONObject jsonObject = RequestUtils.getJwtPayload();
- String jti = jsonObject.getStr("jti"); // JWT唯一标识
- long exp = jsonObject.getLong("exp"); // JWT过期时间戳
+ String jti = jsonObject.getStr(AuthConstants.JWT_JTI); // JWT唯一标识
+ long exp = jsonObject.getLong(AuthConstants.JWT_EXP); // JWT过期时间戳
long currentTimeSeconds = System.currentTimeMillis() / 1000;
diff --git a/youlai-common/common-core/src/main/java/com/youlai/common/constant/AuthConstants.java b/youlai-common/common-core/src/main/java/com/youlai/common/constant/AuthConstants.java
index 8bdc47b5767d806d9dad6f172101f63ef352ad27..2ac37c13ad64ab39713919de22ebf4d1067bd589 100644
--- a/youlai-common/common-core/src/main/java/com/youlai/common/constant/AuthConstants.java
+++ b/youlai-common/common-core/src/main/java/com/youlai/common/constant/AuthConstants.java
@@ -11,7 +11,7 @@ public interface AuthConstants {
/**
* JWT令牌前缀
*/
- String JWT_PREFIX = "bearer ";
+ String AUTHORIZATION_PREFIX = "bearer ";
/**
@@ -24,6 +24,16 @@ public interface AuthConstants {
*/
String JWT_PAYLOAD_KEY = "payload";
+ /**
+ * JWT ID 唯一标识
+ */
+ String JWT_JTI = "jti";
+
+ /**
+ * JWT ID 唯一标识
+ */
+ String JWT_EXP = "exp";
+
/**
* Redis缓存权限规则key
*/
@@ -51,7 +61,7 @@ public interface AuthConstants {
String USER_ID_KEY = "user_id";
- String USER_NAME_KEY="username";
+ String USER_NAME_KEY = "username";
String CLIENT_ID_KEY = "client_id";
@@ -83,5 +93,10 @@ public interface AuthConstants {
String ADMIN_URL_PATTERN = "*_/youlai-admin/**";
- String LOGOUT_PATH= "/youlai-auth/oauth/logout";
+ String LOGOUT_PATH = "/youlai-auth/oauth/logout";
+
+
+ String GRANT_TYPE_KEY = "grant_type";
+
+ String REFRESH_TOKEN = "refresh_token";
}
diff --git a/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/config/RestHighLevelClientConfig.java b/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/config/RestHighLevelClientConfig.java
index 4928282a3ca7e366d7a1411e383c7df2e9cdb2f7..11920088a62336dbbec6b0102003b7a9516b8c9b 100644
--- a/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/config/RestHighLevelClientConfig.java
+++ b/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/config/RestHighLevelClientConfig.java
@@ -12,7 +12,7 @@ import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
- * Ela
+ * ElasticSearch HighLevelClient
*
* @author hxr
* @date 2021-03-05
diff --git a/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/service/ElasticSearchService.java b/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/service/ElasticSearchService.java
index 37e83f219d42484aeb675f7eaaf164882b40f7ee..b22cdad1f538895a8601d578a78efaef36b49859 100644
--- a/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/service/ElasticSearchService.java
+++ b/youlai-common/common-elasticsearch/src/main/java/com/youlai/common/elasticsearch/service/ElasticSearchService.java
@@ -21,6 +21,7 @@ import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInter
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.ParsedDateHistogram;
import org.elasticsearch.search.builder.SearchSourceBuilder;
+import org.elasticsearch.search.sort.SortBuilder;
import org.springframework.stereotype.Service;
import java.util.*;
@@ -39,12 +40,9 @@ public class ElasticSearchService {
@SneakyThrows
public long count(QueryBuilder queryBuilder, String... indices) {
- // 构造搜索条件
- SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
- searchSourceBuilder.query(queryBuilder);
// 构造请求
CountRequest countRequest = new CountRequest(indices);
- countRequest.source(searchSourceBuilder);
+ countRequest.query(queryBuilder);
// 执行请求
CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
long count = countResponse.getCount();
@@ -53,10 +51,11 @@ public class ElasticSearchService {
/**
* 日期统计
+ *
* @param queryBuilder 查询条件
- * @param field 聚合字段,如:登录日志的 date 字段
- * @param interval 统计时间间隔,如:1天、1周
- * @param indices 索引名称
+ * @param field 聚合字段,如:登录日志的 date 字段
+ * @param interval 统计时间间隔,如:1天、1周
+ * @param indices 索引名称
* @return
*/
@SneakyThrows
@@ -107,11 +106,25 @@ public class ElasticSearchService {
@SneakyThrows
public List search(QueryBuilder queryBuilder, Class clazz, String... indices) {
+ List list = this.search(queryBuilder, null, 1, ESConstants.DEFAULT_PAGE_SIZE, clazz, indices);
+ return list;
+ }
+
+
+ @SneakyThrows
+ public List search(QueryBuilder queryBuilder, Integer page, Integer size, Class clazz, String... indices) {
+ List list = this.search(queryBuilder, null, 1, ESConstants.DEFAULT_PAGE_SIZE, clazz, indices);
+ return list;
+ }
+
+ @SneakyThrows
+ public List search(QueryBuilder queryBuilder, SortBuilder sortBuilder, Integer page, Integer size, Class clazz, String... indices) {
// 构造SearchSourceBuilder
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(queryBuilder);
- searchSourceBuilder.from(0);
- searchSourceBuilder.size(ESConstants.DEFAULT_PAGE_SIZE);
+ searchSourceBuilder.sort(sortBuilder);
+ searchSourceBuilder.from((page - 1) * size);
+ searchSourceBuilder.size(size);
// 构造SearchRequest
SearchRequest searchRequest = new SearchRequest(indices);
searchRequest.source(searchSourceBuilder);
@@ -128,5 +141,4 @@ public class ElasticSearchService {
return list;
}
-
}
diff --git a/youlai-common/common-web/pom.xml b/youlai-common/common-web/pom.xml
index b63a2d40abc97aeefccfaa9a3d05695dd1cbf4e6..116430c8b6f73a83a270d00d5b0b084beeb1dd87 100644
--- a/youlai-common/common-web/pom.xml
+++ b/youlai-common/common-web/pom.xml
@@ -28,12 +28,6 @@
true
-
- com.github.dozermapper
- dozer-core
- 6.2.0
-
-
org.springframework.boot
spring-boot-starter-aop
@@ -51,6 +45,18 @@
logstash-logback-encoder
+
+ org.lionsoul
+ ip2region
+
+
+
+
+ com.github.dozermapper
+ dozer-core
+ 6.2.0
+
+
diff --git a/youlai-common/common-web/src/main/java/com/youlai/common/web/aspect/LoginLogAspect.java b/youlai-common/common-web/src/main/java/com/youlai/common/web/aspect/LoginLogAspect.java
index 15f986cb540bcfc3f1a85825bd0378bb8a89791e..e6e5e0c1d628889adc0e863dec9051f56a98e41e 100644
--- a/youlai-common/common-web/src/main/java/com/youlai/common/web/aspect/LoginLogAspect.java
+++ b/youlai-common/common-web/src/main/java/com/youlai/common/web/aspect/LoginLogAspect.java
@@ -1,13 +1,10 @@
package com.youlai.common.web.aspect;
import cn.hutool.core.util.StrUtil;
-import cn.hutool.extra.servlet.ServletUtil;
-import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.youlai.common.constant.AuthConstants;
-import com.youlai.common.web.pojo.domain.LoginLog;
-import com.youlai.common.web.util.IpUtils;
+import com.youlai.common.web.util.IPUtils;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -24,8 +21,9 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
/**
* @author hxr
@@ -44,47 +42,50 @@ public class LoginLogAspect {
@Around("Log()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
- // 时间统计
- Date now = new Date();
- long startTime = now.getTime();
- Object result = joinPoint.proceed();
- long endTime = System.currentTimeMillis();
- long elapsedTime = endTime - startTime;
- // 获取方法签名
- MethodSignature signature = (MethodSignature) joinPoint.getSignature();
- String description = signature.getMethod().getAnnotation(ApiOperation.class).value();
+ LocalDateTime startTime = LocalDateTime.now();
+ Object result = joinPoint.proceed();
// 获取请求信息
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
- // String clientIP = ServletUtil.getClientIP(request);
- String clientIP= IpUtils.getIpAddr(request);
- String requestUrl = request.getRequestURL().toString();
- String method = request.getMethod();
- // MDC 扩展logback字段,具体请看logback-spring.xml的自定义日志输出格式
- MDC.put("elapsedTime", StrUtil.toString(elapsedTime));
- MDC.put("description", description);
- MDC.put("clientIP", clientIP);
- MDC.put("url", requestUrl);
- MDC.put("method", method);
+ // 刷新token不记录
+ String grantType=request.getParameter(AuthConstants.GRANT_TYPE_KEY);
+ if(grantType.equals(AuthConstants.REFRESH_TOKEN)){
+ return result;
+ }
- String username = request.getParameter(AuthConstants.USER_NAME_KEY);
- MDC.put("username", username);
+ // 时间统计
+ LocalDateTime endTime = LocalDateTime.now();
+ long elapsedTime = Duration.between(startTime, endTime).toMillis(); // 请求耗时(毫秒)
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
- String date = simpleDateFormat.format(now);
- MDC.put("date", date);
+ // 获取接口描述信息
+ MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+ String description = signature.getMethod().getAnnotation(ApiOperation.class).value();// 方法描述
+
+ String username = request.getParameter(AuthConstants.USER_NAME_KEY); // 登录用户名
+ String date = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 索引名需要,因为默认生成索引的date时区不一致
- // 获取登录结果
- String accessToken = Strings.EMPTY;
+ // 获取token
+ String token = Strings.EMPTY;
if (request != null) {
JSONObject jsonObject = JSONUtil.parseObj(result);
- accessToken = jsonObject.getStr("value");
+ token = jsonObject.getStr("value");
}
- MDC.put("accessToken", accessToken);
- log.info("{} 登录,耗费时间 {} 毫秒", username, elapsedTime); // 收集日志这里必须打印一条日志,内容随便
+ String clientIP = IPUtils.getClientIP(request); // 客户端请求IP(注意:如果使用Nginx代理需配置)
+ String region = IPUtils.ip2region(clientIP); // IP对应的城市信息
+
+ // MDC 扩展logback字段,具体请看logback-spring.xml的自定义日志输出格式
+ MDC.put("elapsedTime", StrUtil.toString(elapsedTime));
+ MDC.put("description", description);
+ MDC.put("region", region);
+ MDC.put("username", username);
+ MDC.put("date", date);
+ MDC.put("token", token);
+ MDC.put("clientIP", clientIP);
+
+ log.info("{} 登录,耗费时间 {} 毫秒", username, elapsedTime); // 收集日志这里必须打印一条日志,内容随便吧,记录在message字段,具体看logback-spring.xml文件
return result;
}
}
diff --git a/youlai-common/common-web/src/main/java/com/youlai/common/web/pojo/domain/LoginLog.java b/youlai-common/common-web/src/main/java/com/youlai/common/web/pojo/domain/LoginLog.java
deleted file mode 100644
index 7f1d07f6f8ec479b5f47406c26dcab4d479b1048..0000000000000000000000000000000000000000
--- a/youlai-common/common-web/src/main/java/com/youlai/common/web/pojo/domain/LoginLog.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.youlai.common.web.pojo.domain;
-
-import lombok.Data;
-
-/**
- * @Author haoxr
- * @Date 2021-03-01 16:45
- * @Version 1.0.0
- */
-@Data
-public class LoginLog {
-
- private String description;
-
- private String clientIP;
-
- private String url;
-
- private String method;
-
- private long elapsedTime;
-
- private Object result;
-
-}
diff --git a/youlai-common/common-web/src/main/java/com/youlai/common/web/util/IpUtils.java b/youlai-common/common-web/src/main/java/com/youlai/common/web/util/IPUtils.java
similarity index 59%
rename from youlai-common/common-web/src/main/java/com/youlai/common/web/util/IpUtils.java
rename to youlai-common/common-web/src/main/java/com/youlai/common/web/util/IPUtils.java
index 41bba04f35c92fbfa0e9500d43a678a5d96eac0b..ca37484d36fbf760fdb9c1c2abab301156ce699b 100644
--- a/youlai-common/common-web/src/main/java/com/youlai/common/web/util/IpUtils.java
+++ b/youlai-common/common-web/src/main/java/com/youlai/common/web/util/IPUtils.java
@@ -2,20 +2,29 @@ package com.youlai.common.web.util;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.util.Strings;
+import org.lionsoul.ip2region.DataBlock;
+import org.lionsoul.ip2region.DbConfig;
+import org.lionsoul.ip2region.DbSearcher;
+import org.lionsoul.ip2region.Util;
import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Slf4j
-public class IpUtils {
+public class IPUtils {
+
+ private static String LOCAL_IP="127.0.0.1";
/**
* 获取IP地址
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
- public static String getIpAddr(HttpServletRequest request) {
+ public static String getClientIP(HttpServletRequest request) {
String ip = null;
try {
if (request == null) {
@@ -46,10 +55,8 @@ public class IpUtils {
}
//使用代理,则获取第一个IP地址
- if (StrUtil.isEmpty(ip) && ip.length() > 15) {
- if (ip.indexOf(",") > 0) {
- ip = ip.substring(0, ip.indexOf(","));
- }
+ if (StrUtil.isNotBlank(ip) && ip.indexOf(",") > 0) {
+ ip = ip.substring(0, ip.indexOf(","));
}
return ip;
@@ -71,4 +78,43 @@ public class IpUtils {
}
return null;
}
+
+
+ /**
+ * 解析IP获取城市区域信息
+ *
+ * @param ip
+ * @return
+ */
+ public static String ip2region(String ip) {
+ if (Util.isIpAddress(ip) == false) {
+ return Strings.EMPTY;
+ }
+
+ if(LOCAL_IP.equals(ip)){
+ return "本地访问";
+ }
+
+ String filePath = IPUtils.class.getResource("/data/ip2region.db").getPath();
+ File file = new File(filePath);
+ if (file.exists() == false) {
+ return Strings.EMPTY;
+ }
+
+ try {
+ DbConfig config = new DbConfig();
+ DbSearcher searcher = new DbSearcher(config, filePath);
+
+ Method method = searcher.getClass().getMethod("btreeSearch", String.class);
+ DataBlock dataBlock = (DataBlock) method.invoke(searcher, ip);
+
+ return dataBlock.getRegion();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return Strings.EMPTY;
+ }
+
+
}