Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
有来技术
youlai-mall
提交
d35c3f23
Y
youlai-mall
项目概览
有来技术
/
youlai-mall
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
youlai-mall
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
d35c3f23
编写于
3月 10, 2021
作者:
H
haoxr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:添加强制会话失效功能
上级
a5757bed
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
180 addition
and
32 deletion
+180
-32
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsCategoryService.java
...java/com/youlai/mall/pms/service/IPmsCategoryService.java
+1
-1
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsCategoryServiceImpl.java
.../youlai/mall/pms/service/impl/PmsCategoryServiceImpl.java
+1
-1
youlai-admin/admin-api/src/main/java/com/youlai/admin/pojo/domain/LoginRecord.java
...c/main/java/com/youlai/admin/pojo/domain/LoginRecord.java
+5
-2
youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/util/JWTUtils.java
.../src/main/java/com/youlai/admin/common/util/JWTUtils.java
+48
-0
youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/LoginRecordController.java
...va/com/youlai/admin/controller/LoginRecordController.java
+12
-0
youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/TokenController.java
...ain/java/com/youlai/admin/controller/TokenController.java
+10
-27
youlai-admin/admin-boot/src/main/java/com/youlai/admin/service/ITokenService.java
...src/main/java/com/youlai/admin/service/ITokenService.java
+24
-0
youlai-admin/admin-boot/src/main/java/com/youlai/admin/service/impl/TokenServiceImpl.java
.../java/com/youlai/admin/service/impl/TokenServiceImpl.java
+63
-0
youlai-common/common-core/src/main/java/com/youlai/common/domain/JWTPayload.java
...re/src/main/java/com/youlai/common/domain/JWTPayload.java
+15
-0
youlai-common/common-web/src/main/java/com/youlai/common/web/vo/CascaderVO.java
...eb/src/main/java/com/youlai/common/web/vo/CascaderVO.java
+1
-1
未找到文件。
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/IPmsCategoryService.java
浏览文件 @
d35c3f23
package
com.youlai.mall.pms.service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.youlai.common.web.
pojo.
vo.CascaderVO
;
import
com.youlai.common.web.vo.CascaderVO
;
import
com.youlai.mall.pms.pojo.domain.PmsCategory
;
import
com.youlai.mall.pms.pojo.vo.CategoryVO
;
...
...
mall-pms/pms-boot/src/main/java/com/youlai/mall/pms/service/impl/PmsCategoryServiceImpl.java
浏览文件 @
d35c3f23
...
...
@@ -3,7 +3,7 @@ package com.youlai.mall.pms.service.impl;
import
cn.hutool.core.bean.BeanUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.youlai.common.web.
pojo.
vo.CascaderVO
;
import
com.youlai.common.web.vo.CascaderVO
;
import
com.youlai.mall.pms.pojo.domain.PmsCategory
;
import
com.youlai.mall.pms.mapper.PmsCategoryMapper
;
import
com.youlai.mall.pms.service.IPmsCategoryService
;
...
...
youlai-admin/admin-api/src/main/java/com/youlai/admin/pojo/domain/LoginRecord.java
浏览文件 @
d35c3f23
...
...
@@ -10,8 +10,6 @@ import lombok.Data;
@Data
public
class
LoginRecord
extends
BaseDocument
{
private
String
description
;
private
String
clientIP
;
private
long
elapsedTime
;
...
...
@@ -26,4 +24,9 @@ public class LoginRecord extends BaseDocument {
private
String
region
;
/**
* 会话状态 0-离线 1-在线
*/
private
Integer
status
;
}
youlai-admin/admin-boot/src/main/java/com/youlai/admin/common/util/JWTUtils.java
0 → 100644
浏览文件 @
d35c3f23
package
com.youlai.admin.common.util
;
import
cn.hutool.json.JSONUtil
;
import
com.nimbusds.jose.JWSObject
;
import
com.youlai.common.constant.AuthConstants
;
import
com.youlai.common.domain.JWTPayload
;
import
lombok.SneakyThrows
;
import
org.apache.logging.log4j.util.Strings
;
/**
* @author hxr
* @date 2021-03-10
*/
public
class
JWTUtils
{
/**
* 获取JWT的载体
* @param token
* @return
*/
@SneakyThrows
public
static
JWTPayload
getJWTPayload
(
String
token
)
{
token
=
token
.
replace
(
AuthConstants
.
AUTHORIZATION_PREFIX
,
Strings
.
EMPTY
);
JWSObject
jwsObject
=
JWSObject
.
parse
(
token
);
JWTPayload
payload
=
JSONUtil
.
toBean
(
jwsObject
.
getPayload
().
toString
(),
JWTPayload
.
class
);
return
payload
;
}
/**
* 判断token是否过期
* @param token
* @return
*/
public
static
boolean
isExpired
(
String
token
)
{
JWTPayload
payload
=
getJWTPayload
(
token
);
// 计算是否过期
long
currentTimeSeconds
=
System
.
currentTimeMillis
()
/
1000
;
Long
exp
=
payload
.
getExp
();
if
(
exp
<
currentTimeSeconds
)
{
// token已过期,无需加入黑名单
return
true
;
}
return
false
;
}
}
youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/LoginRecordController.java
浏览文件 @
d35c3f23
...
...
@@ -3,6 +3,7 @@ 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.admin.service.ITokenService
;
import
com.youlai.common.base.BaseDocument
;
import
com.youlai.common.elasticsearch.service.ElasticSearchService
;
import
com.youlai.common.result.Result
;
...
...
@@ -18,6 +19,7 @@ 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
;
/**
...
...
@@ -33,6 +35,8 @@ public class LoginRecordController {
ElasticSearchService
elasticSearchService
;
ITokenService
tokenService
;
@ApiOperation
(
value
=
"列表分页"
,
httpMethod
=
"GET"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"page"
,
value
=
"页码"
,
defaultValue
=
"1"
,
paramType
=
"query"
,
dataType
=
"Long"
),
...
...
@@ -73,6 +77,13 @@ public class LoginRecordController {
// 分页查询
List
<
LoginRecord
>
list
=
elasticSearchService
.
search
(
queryBuilder
,
sortBuilder
,
page
,
limit
,
LoginRecord
.
class
,
ESConstants
.
LOGIN_INDEX_PATTERN
);
// 遍历获取会话状态
list
.
forEach
(
item
->{
int
tokenStatus
=
tokenService
.
getTokenStatus
(
item
.
getToken
());
item
.
setStatus
(
tokenStatus
);
});
return
Result
.
success
(
list
,
count
);
}
...
...
@@ -84,4 +95,5 @@ public class LoginRecordController {
documents
.
forEach
(
document
->
elasticSearchService
.
deleteById
(
document
.
getId
(),
document
.
getIndex
()));
return
Result
.
success
();
}
}
youlai-admin/admin-boot/src/main/java/com/youlai/admin/controller/TokenController.java
浏览文件 @
d35c3f23
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.admin.service.ITokenService
;
import
com.youlai.common.result.Result
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -11,11 +8,11 @@ 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
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.concurrent.TimeUnit
;
/**
* @author hxr
...
...
@@ -29,29 +26,15 @@ import java.util.concurrent.TimeUnit;
@AllArgsConstructor
public
class
TokenController
{
RedisTemplate
redisTemplat
e
;
ITokenService
tokenServic
e
;
@ApiOperation
(
value
=
"强制下线"
,
httpMethod
=
"POST"
)
@ApiImplicitParam
(
name
=
"token"
,
value
=
"访问令牌"
,
required
=
true
,
paramType
=
"query"
,
dataType
=
"String"
)
@PostMapping
(
"/{token}/_invalid"
)
@PostMapping
(
"/{token}/_invalid
ate
"
)
@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
();
public
Result
invalidateToken
(
@PathVariable
String
token
)
{
boolean
status
=
tokenService
.
invalidateToken
(
token
);
return
Result
.
judge
(
status
);
}
}
youlai-admin/admin-boot/src/main/java/com/youlai/admin/service/ITokenService.java
0 → 100644
浏览文件 @
d35c3f23
package
com.youlai.admin.service
;
import
java.text.ParseException
;
public
interface
ITokenService
{
/**
* 使令牌token失效
*
* @param token
* @return
*/
boolean
invalidateToken
(
String
token
)
throws
ParseException
;
/**
* 获取token状态
* @param token
* @return 1-有效,0-失效(过期或被加入黑名单)
*/
int
getTokenStatus
(
String
token
);
}
youlai-admin/admin-boot/src/main/java/com/youlai/admin/service/impl/TokenServiceImpl.java
0 → 100644
浏览文件 @
d35c3f23
package
com.youlai.admin.service.impl
;
import
com.youlai.admin.common.util.JWTUtils
;
import
com.youlai.admin.service.ITokenService
;
import
com.youlai.common.constant.AuthConstants
;
import
com.youlai.common.domain.JWTPayload
;
import
lombok.AllArgsConstructor
;
import
lombok.SneakyThrows
;
import
org.springframework.data.redis.core.RedisTemplate
;
import
org.springframework.stereotype.Service
;
import
java.util.concurrent.TimeUnit
;
/**
* @author haoxr
* @date 2021-03-10
*/
@Service
@AllArgsConstructor
public
class
TokenServiceImpl
implements
ITokenService
{
RedisTemplate
redisTemplate
;
@Override
@SneakyThrows
public
boolean
invalidateToken
(
String
token
)
{
JWTPayload
payload
=
JWTUtils
.
getJWTPayload
(
token
);
// 计算是否过期
long
currentTimeSeconds
=
System
.
currentTimeMillis
()
/
1000
;
Long
exp
=
payload
.
getExp
();
if
(
exp
<
currentTimeSeconds
)
{
// token已过期,无需加入黑名单
return
true
;
}
// 添加至黑名单使其失效
redisTemplate
.
opsForValue
().
set
(
AuthConstants
.
TOKEN_BLACKLIST_PREFIX
+
payload
.
getJti
(),
null
,
(
exp
-
currentTimeSeconds
),
TimeUnit
.
SECONDS
);
return
true
;
}
@Override
public
int
getTokenStatus
(
String
token
)
{
JWTPayload
payload
=
JWTUtils
.
getJWTPayload
(
token
);
// 计算是否过期
long
currentTimeSeconds
=
System
.
currentTimeMillis
()
/
1000
;
Long
exp
=
payload
.
getExp
();
if
(
exp
<
currentTimeSeconds
)
{
// token已过期 返回失效
return
0
;
}
// 判断是否存在黑名单
String
jti
=
payload
.
getJti
();
Boolean
isExists
=
redisTemplate
.
hasKey
(
AuthConstants
.
TOKEN_BLACKLIST_PREFIX
+
jti
);
if
(
isExists
==
true
)
{
// 被添加到黑名单 返回失效
return
0
;
}
return
1
;
}
}
youlai-common/common-core/src/main/java/com/youlai/common/domain/JWTPayload.java
0 → 100644
浏览文件 @
d35c3f23
package
com.youlai.common.domain
;
import
lombok.Data
;
/**
* @author hxr
* @date 2021-03-10
*/
@Data
public
class
JWTPayload
{
private
String
jti
;
private
Long
exp
;
}
youlai-common/common-web/src/main/java/com/youlai/common/web/
pojo/
vo/CascaderVO.java
→
youlai-common/common-web/src/main/java/com/youlai/common/web/vo/CascaderVO.java
浏览文件 @
d35c3f23
package
com.youlai.common.web.
pojo.
vo
;
package
com.youlai.common.web.vo
;
import
com.fasterxml.jackson.annotation.JsonInclude
;
import
lombok.Data
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录