Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cloud-backend
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
framework
cloud-backend
Commits
e67bc01a
Commit
e67bc01a
authored
May 30, 2022
by
袁伟铭
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.0.0
parent
4809b2b9
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
497 additions
and
303 deletions
+497
-303
admin-server/src/main/java/com/zq/admin/config/security/SpringSecurityConfig.java
+0
-1
admin-server/src/main/java/com/zq/admin/config/security/TokenConfigurer.java
+0
-1
admin-server/src/main/java/com/zq/admin/config/security/TokenFilter.java
+0
-1
admin-server/src/main/java/com/zq/admin/config/security/TokenProvider.java
+117
-117
admin-server/src/main/java/com/zq/admin/modules/security/rest/AuthorizationController.java
+1
-1
api-server/src/main/java/com/zq/api/config/FeignConfig.java
+2
-1
api-server/src/main/java/com/zq/api/controller/ApiController.java
+11
-2
api-server/src/main/java/com/zq/api/controller/AppController.java
+145
-0
api-server/src/main/java/com/zq/api/form/ApiForm.java
+26
-3
api-server/src/main/java/com/zq/api/service/ApiService.java
+40
-11
api-server/src/main/java/com/zq/api/service/AppService.java
+91
-0
api-server/src/main/java/com/zq/api/service/impl/BaseApiLogic.java
+1
-1
api-server/src/main/java/com/zq/api/utils/ApiUtils.java
+19
-19
logging-server/src/main/java/com/zq/logging/constant/Constant.java
+2
-2
logging-server/src/main/java/com/zq/logging/utils/RequestUtils.java
+2
-2
user-server/src/main/java/com/zq/user/config/SpringSecurityConfig.java
+0
-1
user-server/src/main/java/com/zq/user/config/TokenConfigurer.java
+0
-1
user-server/src/main/java/com/zq/user/config/TokenFilter.java
+0
-1
user-server/src/main/java/com/zq/user/config/TokenProvider.java
+0
-0
xxx-common-utils/src/main/java/com/zq/common/config/base/UnifiedExceptionHandler.java
+6
-2
xxx-common-utils/src/main/java/com/zq/common/config/security/TokenProvider.java
+0
-136
xxx-common-utils/src/main/java/com/zq/common/constant/FeignHeader.java
+21
-0
xxx-common-utils/src/main/java/com/zq/common/constant/SystemName.java
+13
-0
No files found.
admin-server/src/main/java/com/zq/admin/config/security/SpringSecurityConfig.java
View file @
e67bc01a
...
@@ -19,7 +19,6 @@ import com.zq.admin.modules.security.service.OnlineUserService;
...
@@ -19,7 +19,6 @@ import com.zq.admin.modules.security.service.OnlineUserService;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.common.annotation.AnonymousAccess
;
import
com.zq.common.annotation.AnonymousAccess
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
com.zq.common.utils.RequestMethodEnum
;
import
com.zq.common.utils.RequestMethodEnum
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
...
...
admin-server/src/main/java/com/zq/admin/config/security/TokenConfigurer.java
View file @
e67bc01a
...
@@ -18,7 +18,6 @@ package com.zq.admin.config.security;
...
@@ -18,7 +18,6 @@ package com.zq.admin.config.security;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
...
...
admin-server/src/main/java/com/zq/admin/config/security/TokenFilter.java
View file @
e67bc01a
...
@@ -19,7 +19,6 @@ import cn.hutool.core.util.StrUtil;
...
@@ -19,7 +19,6 @@ import cn.hutool.core.util.StrUtil;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.admin.modules.security.service.UserCacheManager
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
com.zq.common.context.ContextUtils
;
import
com.zq.common.context.ContextUtils
;
import
com.zq.common.vo.OnlineUserDto
;
import
com.zq.common.vo.OnlineUserDto
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
io.jsonwebtoken.ExpiredJwtException
;
...
...
admin-server/src/main/java/com/zq/admin/config/security/TokenProvider.java
View file @
e67bc01a
//
package com.zq.admin.config.security;/*
package
com
.
zq
.
admin
.
config
.
security
;
/*
//
* Copyright 2019-2020 Zheng Jie
* Copyright 2019-2020 Zheng Jie
//
*
*
//
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
//
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
//
* You may obtain a copy of the License at
* You may obtain a copy of the License at
//
*
*
//
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
//
*
*
//
* Unless required by applicable law or agreed to in writing, software
* Unless required by applicable law or agreed to in writing, software
//
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an "AS IS" BASIS,
//
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
* See the License for the specific language governing permissions and
* See the License for the specific language governing permissions and
//
* limitations under the License.
* limitations under the License.
//
*/
*/
//
//
import cn.hutool.core.date.DateField;
import
cn.hutool.core.date.DateField
;
//
import cn.hutool.core.date.DateUtil;
import
cn.hutool.core.date.DateUtil
;
//
import cn.hutool.core.util.IdUtil;
import
cn.hutool.core.util.IdUtil
;
//
import com.zq.common.config.redis.RedisUtils;
import
com.zq.common.config.redis.RedisUtils
;
//
import com.zq.common.config.security.SecurityProperties;
import
com.zq.common.config.security.SecurityProperties
;
//
import io.jsonwebtoken.Claims;
import
io.jsonwebtoken.Claims
;
//
import io.jsonwebtoken.Jwts;
import
io.jsonwebtoken.Jwts
;
//
import io.jsonwebtoken.SignatureAlgorithm;
import
io.jsonwebtoken.SignatureAlgorithm
;
//
import lombok.RequiredArgsConstructor;
import
lombok.RequiredArgsConstructor
;
//
import lombok.extern.slf4j.Slf4j;
import
lombok.extern.slf4j.Slf4j
;
//
import org.apache.commons.lang3.StringUtils;
import
org.apache.commons.lang3.StringUtils
;
//
import org.springframework.beans.factory.InitializingBean;
import
org.springframework.beans.factory.InitializingBean
;
//
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
//
import org.springframework.security.core.Authentication;
import
org.springframework.security.core.Authentication
;
//
import org.springframework.security.core.userdetails.User;
import
org.springframework.security.core.userdetails.User
;
//
import org.springframework.stereotype.Component;
import
org.springframework.stereotype.Component
;
//
//
import javax.crypto.spec.SecretKeySpec;
import
javax.crypto.spec.SecretKeySpec
;
//
import javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletRequest
;
//
import javax.xml.bind.DatatypeConverter;
import
javax.xml.bind.DatatypeConverter
;
//
import java.security.Key;
import
java.security.Key
;
//
import java.util.ArrayList;
import
java.util.ArrayList
;
//
import java.util.Date;
import
java.util.Date
;
//
import java.util.concurrent.TimeUnit;
import
java.util.concurrent.TimeUnit
;
//
/
/ /
**
/**
//
* @author /
* @author /
//
*/
*/
//
@Slf4j
@Slf4j
//
@Component
@Component
//
@RequiredArgsConstructor
@RequiredArgsConstructor
//
public class TokenProvider implements InitializingBean {
public
class
TokenProvider
implements
InitializingBean
{
//
//
private final RedisUtils redisUtils;
private
final
RedisUtils
redisUtils
;
//
private final SecurityProperties properties;
private
final
SecurityProperties
properties
;
//
//
public static final String AUTHORITIES_KEY = "auth";
public
static
final
String
AUTHORITIES_KEY
=
"auth"
;
//
private static Key key;
private
static
Key
key
;
//
private static SignatureAlgorithm signatureAlgorithm;
private
static
SignatureAlgorithm
signatureAlgorithm
;
//
//
@Override
@Override
//
public void afterPropertiesSet() {
public
void
afterPropertiesSet
()
{
//
signatureAlgorithm = SignatureAlgorithm.HS512;
signatureAlgorithm
=
SignatureAlgorithm
.
HS512
;
//
byte[] keyBytes = DatatypeConverter.parseBase64Binary(properties.getBase64Secret());
byte
[]
keyBytes
=
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
());
//
key = new SecretKeySpec(keyBytes, signatureAlgorithm.getJcaName());
key
=
new
SecretKeySpec
(
keyBytes
,
signatureAlgorithm
.
getJcaName
());
//
}
}
//
//
public static String createToken(Authentication authentication) {
public
static
String
createToken
(
Authentication
authentication
)
{
//
return Jwts.builder()
return
Jwts
.
builder
()
//
.claim(AUTHORITIES_KEY, authentication.getName())
.
claim
(
AUTHORITIES_KEY
,
authentication
.
getName
())
//
.setSubject(authentication.getName())
.
setSubject
(
authentication
.
getName
())
//
.signWith(signatureAlgorithm, key)
.
signWith
(
signatureAlgorithm
,
key
)
//
// 加入ID确保生成的 Token 都不一致
// 加入ID确保生成的 Token 都不一致
//
.setId(IdUtil.simpleUUID())
.
setId
(
IdUtil
.
simpleUUID
())
//
.compact();
.
compact
();
//
}
}
//
//
public Claims getClaims(String token) {
public
Claims
getClaims
(
String
token
)
{
//
return Jwts.parser()
return
Jwts
.
parser
()
//
.setSigningKey(DatatypeConverter.parseBase64Binary(properties.getBase64Secret()))
.
setSigningKey
(
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
()))
//
.parseClaimsJws(token)
.
parseClaimsJws
(
token
)
//
.getBody();
.
getBody
();
//
}
}
//
//
public Authentication getAuthentication(String token) {
public
Authentication
getAuthentication
(
String
token
)
{
//
Claims claims = getClaims(token);
Claims
claims
=
getClaims
(
token
);
//
User principal = new User(claims.getSubject(), "******", new ArrayList<>());
User
principal
=
new
User
(
claims
.
getSubject
(),
"******"
,
new
ArrayList
<>());
//
return new UsernamePasswordAuthenticationToken(principal, token, new ArrayList<>());
return
new
UsernamePasswordAuthenticationToken
(
principal
,
token
,
new
ArrayList
<>());
//
}
}
//
//
/**
/**
//
* @param token 需要检查的token
* @param token 需要检查的token
//
*/
*/
//
public void checkRenewal(String token) {
public
void
checkRenewal
(
String
token
)
{
//
// 判断是否续期token,计算token的过期时间
// 判断是否续期token,计算token的过期时间
//
long time = redisUtils.getExpire(properties.getOnlineKey() + token) * 1000;
long
time
=
redisUtils
.
getExpire
(
properties
.
getOnlineKey
()
+
token
)
*
1000
;
//
Date expireDate = DateUtil.offset(new Date(), DateField.MILLISECOND, (int) time);
Date
expireDate
=
DateUtil
.
offset
(
new
Date
(),
DateField
.
MILLISECOND
,
(
int
)
time
);
//
// 判断当前时间与过期时间的时间差
// 判断当前时间与过期时间的时间差
//
long differ = expireDate.getTime() - System.currentTimeMillis();
long
differ
=
expireDate
.
getTime
()
-
System
.
currentTimeMillis
();
//
// 如果在续期检查的范围内,则续期
// 如果在续期检查的范围内,则续期
//
if (differ <= properties.getDetect()) {
if
(
differ
<=
properties
.
getDetect
())
{
//
long renew = time + properties.getRenew();
long
renew
=
time
+
properties
.
getRenew
();
//
redisUtils.expire(properties.getOnlineKey() + token, renew, TimeUnit.MILLISECONDS);
redisUtils
.
expire
(
properties
.
getOnlineKey
()
+
token
,
renew
,
TimeUnit
.
MILLISECONDS
);
//
}
}
//
}
}
//
//
public String getToken(HttpServletRequest request) {
public
String
getToken
(
HttpServletRequest
request
)
{
//
String bearerToken = request.getHeader(properties.getHeader());
String
bearerToken
=
request
.
getHeader
(
properties
.
getHeader
());
//
if (StringUtils.isBlank(bearerToken)) {
if
(
StringUtils
.
isBlank
(
bearerToken
))
{
//
return null;
return
null
;
//
}
}
//
if (bearerToken.startsWith(properties.getTokenStartWith())) {
if
(
bearerToken
.
startsWith
(
properties
.
getTokenStartWith
()))
{
//
// 去掉令牌前缀
// 去掉令牌前缀
//
return bearerToken.replace(properties.getTokenStartWith(), "");
return
bearerToken
.
replace
(
properties
.
getTokenStartWith
(),
""
);
//
} else {
}
else
{
//
log.debug("非法Token:{}", bearerToken);
log
.
debug
(
"非法Token:{}"
,
bearerToken
);
//
}
}
//
return null;
return
null
;
//
}
}
//
//
}
}
admin-server/src/main/java/com/zq/admin/modules/security/rest/AuthorizationController.java
View file @
e67bc01a
...
@@ -20,6 +20,7 @@ import com.wf.captcha.base.Captcha;
...
@@ -20,6 +20,7 @@ import com.wf.captcha.base.Captcha;
import
com.zq.admin.config.RsaProperties
;
import
com.zq.admin.config.RsaProperties
;
import
com.zq.admin.config.bean.LoginCodeEnum
;
import
com.zq.admin.config.bean.LoginCodeEnum
;
import
com.zq.admin.config.bean.LoginProperties
;
import
com.zq.admin.config.bean.LoginProperties
;
import
com.zq.admin.config.security.TokenProvider
;
import
com.zq.admin.exception.BadRequestException
;
import
com.zq.admin.exception.BadRequestException
;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.OnlineUserService
;
import
com.zq.admin.modules.security.service.dto.AuthUserDto
;
import
com.zq.admin.modules.security.service.dto.AuthUserDto
;
...
@@ -31,7 +32,6 @@ import com.zq.common.annotation.rest.AnonymousGetMapping;
...
@@ -31,7 +32,6 @@ import com.zq.common.annotation.rest.AnonymousGetMapping;
import
com.zq.common.annotation.rest.AnonymousPostMapping
;
import
com.zq.common.annotation.rest.AnonymousPostMapping
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiOperation
;
import
io.swagger.annotations.ApiOperation
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
...
...
api-server/src/main/java/com/zq/api/config/FeignConfig.java
View file @
e67bc01a
package
com
.
zq
.
api
.
config
;
package
com
.
zq
.
api
.
config
;
import
com.zq.common.constant.FeignHeader
;
import
feign.RequestInterceptor
;
import
feign.RequestInterceptor
;
import
feign.RequestTemplate
;
import
feign.RequestTemplate
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -55,7 +56,7 @@ public class FeignConfig {
...
@@ -55,7 +56,7 @@ public class FeignConfig {
@Override
@Override
public
void
apply
(
RequestTemplate
template
)
{
public
void
apply
(
RequestTemplate
template
)
{
HttpServletRequest
request
=
((
ServletRequestAttributes
)
Objects
.
requireNonNull
(
RequestContextHolder
.
getRequestAttributes
())).
getRequest
();
HttpServletRequest
request
=
((
ServletRequestAttributes
)
Objects
.
requireNonNull
(
RequestContextHolder
.
getRequestAttributes
())).
getRequest
();
template
.
header
(
"X-App-Token"
,
request
.
getParameter
(
"token"
));
template
.
header
(
FeignHeader
.
API_TOKEN
,
request
.
getParameter
(
"token"
));
Enumeration
<
String
>
headerNames
=
request
.
getHeaderNames
();
Enumeration
<
String
>
headerNames
=
request
.
getHeaderNames
();
if
(
headerNames
!=
null
)
{
if
(
headerNames
!=
null
)
{
while
(
headerNames
.
hasMoreElements
())
{
while
(
headerNames
.
hasMoreElements
())
{
...
...
api-server/src/main/java/com/zq/api/controller/ApiController.java
View file @
e67bc01a
...
@@ -17,6 +17,7 @@ import feign.FeignException;
...
@@ -17,6 +17,7 @@ import feign.FeignException;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.Api
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.RequestHeader
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
...
@@ -43,7 +44,7 @@ public class ApiController {
...
@@ -43,7 +44,7 @@ public class ApiController {
* 2016年10月3日 下午1:38:27
* 2016年10月3日 下午1:38:27
*/
*/
@RequestMapping
(
"/action"
)
@RequestMapping
(
"/action"
)
public
ApiResp
action
(
HttpServletRequest
request
,
ApiForm
form
)
{
public
ApiResp
action
(
HttpServletRequest
request
,
ApiForm
form
,
@RequestHeader
(
required
=
false
)
String
token
)
{
long
start
=
System
.
currentTimeMillis
();
long
start
=
System
.
currentTimeMillis
();
// 不处理Request Method:OPTIONS的请求
// 不处理Request Method:OPTIONS的请求
...
@@ -51,6 +52,7 @@ public class ApiController {
...
@@ -51,6 +52,7 @@ public class ApiController {
return
ApiUtils
.
getSuccessResp
(
form
);
return
ApiUtils
.
getSuccessResp
(
form
);
}
}
form
.
setType
(
2
);
//解析业务参数
//解析业务参数
if
(!
form
.
parseBizContent
())
{
if
(!
form
.
parseBizContent
())
{
return
ApiUtils
.
getParamError
(
form
);
return
ApiUtils
.
getParamError
(
form
);
...
@@ -84,7 +86,12 @@ public class ApiController {
...
@@ -84,7 +86,12 @@ public class ApiController {
// 调用接口方法
// 调用接口方法
ApiResp
resp
;
ApiResp
resp
;
try
{
try
{
// 身份验证
resp
=
apiService
.
auth
(
form
,
token
);
if
(
resp
.
isSuccess
())
{
// 调用接口方法
resp
=
apiService
.
action
(
form
);
resp
=
apiService
.
action
(
form
);
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
error
(
"调用方法异常:{}"
,
e
.
getMessage
());
log
.
error
(
"调用方法异常:{}"
,
e
.
getMessage
());
stackTrace
=
ThrowableUtil
.
getStackTrace
(
e
);
stackTrace
=
ThrowableUtil
.
getStackTrace
(
e
);
...
@@ -95,6 +102,8 @@ public class ApiController {
...
@@ -95,6 +102,8 @@ public class ApiController {
resp
=
ApiUtils
.
toApiResp
(
form
,
ResultVo
.
fail
(
404
,
"NotFound"
));
resp
=
ApiUtils
.
toApiResp
(
form
,
ResultVo
.
fail
(
404
,
"NotFound"
));
}
else
if
(
stackTrace
.
contains
(
"Load balancer does not have available server for client"
))
{
}
else
if
(
stackTrace
.
contains
(
"Load balancer does not have available server for client"
))
{
resp
=
ApiUtils
.
getServiceNotAvailableError
(
form
);
resp
=
ApiUtils
.
getServiceNotAvailableError
(
form
);
}
else
if
(
stackTrace
.
contains
(
"Connection refused: connect executing"
))
{
resp
=
ApiUtils
.
getServiceNotAvailableError
(
form
);
}
else
{
}
else
{
resp
=
ApiUtils
.
getMethodHandlerError
(
form
);
resp
=
ApiUtils
.
getMethodHandlerError
(
form
);
}
}
...
@@ -102,7 +111,7 @@ public class ApiController {
...
@@ -102,7 +111,7 @@ public class ApiController {
// 没有数据输出空
// 没有数据输出空
resp
=
resp
==
null
?
new
ApiResp
(
form
)
:
resp
;
resp
=
resp
==
null
?
new
ApiResp
(
form
)
:
resp
;
String
logType
=
resp
.
isSuccess
()
?
"INFO"
:
"ERROR"
;
String
logType
=
resp
.
isSuccess
()
?
"INFO"
:
"
400"
.
equals
(
resp
.
getCode
())
?
"WARN"
:
"
ERROR"
;
// 如果是500错误, 服务会返回错误的堆栈信息
// 如果是500错误, 服务会返回错误的堆栈信息
if
(
resp
.
getCode
().
equals
(
ApiCodeEnum
.
SERVER_ERROR
.
code
()))
{
if
(
resp
.
getCode
().
equals
(
ApiCodeEnum
.
SERVER_ERROR
.
code
()))
{
...
...
api-server/src/main/java/com/zq/api/controller/AppController.java
0 → 100644
View file @
e67bc01a
package
com
.
zq
.
api
.
controller
;
import
cn.hutool.core.exceptions.ExceptionUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.extra.servlet.ServletUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.zq.api.constant.ApiCodeEnum
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiResp
;
import
com.zq.api.service.AppService
;
import
com.zq.api.utils.ApiUtils
;
import
com.zq.common.config.security.ApiTokenUtils
;
import
com.zq.common.utils.ThrowableUtil
;
import
com.zq.common.vo.ApiTokenVo
;
import
com.zq.common.vo.ResultVo
;
import
feign.FeignException
;
import
io.swagger.annotations.Api
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.Arrays
;
/**
* @author wilmiam
* @since 2021-08-16 15:37
*/
@Api
(
tags
=
"APP接口"
)
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping
(
"/api/app"
)
public
class
AppController
{
private
final
AppService
appService
;
/**
* 允许用户未登录状态下执行的方法名
*/
private
final
String
[]
allowMethod
=
{
"apiLogin"
,
"signinWxLogin"
,
"getSigninWxPhone"
,
"wxLogin"
,
"getWxPhone"
};
/**
* 获取信息入口
* <p>
* 2016年10月3日 下午1:38:27
*/
@RequestMapping
(
"/action"
)
public
ApiResp
action
(
HttpServletRequest
request
,
ApiForm
form
)
{
long
start
=
System
.
currentTimeMillis
();
// 不处理Request Method:OPTIONS的请求
if
(
"OPTIONS"
.
equals
(
request
.
getMethod
()))
{
return
ApiUtils
.
getSuccessResp
(
form
);
}
form
.
setType
(
1
);
//解析业务参数
if
(!
form
.
parseBizContent
())
{
return
ApiUtils
.
getParamError
(
form
);
}
String
method
=
form
.
getMethod
();
if
(
StrUtil
.
isBlank
(
method
))
{
method
=
request
.
getParameter
(
"method"
);
form
.
setMethod
(
method
);
}
if
(
StrUtil
.
isBlank
(
form
.
getToken
()))
{
boolean
contains
=
Arrays
.
asList
(
allowMethod
).
contains
(
method
);
if
(!
contains
)
{
return
ApiUtils
.
getLoginValidError
(
form
);
}
}
ApiTokenVo
tokenVo
=
ApiTokenUtils
.
getAppTokenVo
(
form
.
getToken
());
if
(
tokenVo
==
null
)
{
boolean
contains
=
Arrays
.
asList
(
allowMethod
).
contains
(
method
);
if
(!
contains
)
{
return
ApiUtils
.
getLoginValidError
(
form
);
}
}
else
{
form
.
setUserId
(
String
.
valueOf
(
tokenVo
.
getUserId
()));
form
.
setApiTokenVo
(
tokenVo
);
}
String
stackTrace
=
""
;
// 调用接口方法
ApiResp
resp
;
try
{
resp
=
appService
.
action
(
form
);
}
catch
(
Exception
e
)
{
log
.
error
(
"调用方法异常:{}"
,
e
.
getMessage
());
stackTrace
=
ThrowableUtil
.
getStackTrace
(
e
);
// 判断指定异常是否来自或者包含指定异常
if
(
ExceptionUtil
.
isFromOrSuppressedThrowable
(
e
,
FeignException
.
Unauthorized
.
class
))
{
resp
=
ApiUtils
.
toApiResp
(
form
,
ResultVo
.
fail
(
401
,
"Unauthorized"
));
}
else
if
(
ExceptionUtil
.
isFromOrSuppressedThrowable
(
e
,
FeignException
.
NotFound
.
class
))
{
resp
=
ApiUtils
.
toApiResp
(
form
,
ResultVo
.
fail
(
404
,
"NotFound"
));
}
else
if
(
stackTrace
.
contains
(
"Load balancer does not have available server for client"
))
{
resp
=
ApiUtils
.
getServiceNotAvailableError
(
form
);
}
else
if
(
stackTrace
.
contains
(
"Connection refused: connect executing"
))
{
resp
=
ApiUtils
.
getServiceNotAvailableError
(
form
);
}
else
{
resp
=
ApiUtils
.
getMethodHandlerError
(
form
);
}
}
// 没有数据输出空
resp
=
resp
==
null
?
new
ApiResp
(
form
)
:
resp
;
String
logType
=
resp
.
isSuccess
()
?
"INFO"
:
"400"
.
equals
(
resp
.
getCode
())
?
"WARN"
:
"ERROR"
;
// 如果是500错误, 服务会返回错误的堆栈信息
if
(
resp
.
getCode
().
equals
(
ApiCodeEnum
.
SERVER_ERROR
.
code
()))
{
stackTrace
=
resp
.
getMsg
();
resp
.
setMsg
(
ApiCodeEnum
.
SERVER_ERROR
.
msg
());
}
// 调试日志
if
(
ApiUtils
.
DEBUG
)
{
System
.
out
.
println
(
"API DEBUG ACTION \n[from="
+
form
+
"]"
+
"\n[resp="
+
JSON
.
toJSONString
(
resp
)
+
"]"
+
"\n[time="
+
(
System
.
currentTimeMillis
()
-
start
)
+
"ms]"
);
}
String
clientIp
=
ServletUtil
.
getClientIP
(
request
);
appService
.
addLog
(
form
,
clientIp
,
logType
,
resp
.
getMsg
(),
stackTrace
,
System
.
currentTimeMillis
()
-
start
);
return
resp
;
}
/**
* 开关调试日志
* <p>
* 2016年10月3日 下午5:47:46
*/
@RequestMapping
(
"/debug"
)
public
ApiResp
debug
(
HttpServletRequest
request
)
{
ApiForm
from
=
ServletUtil
.
toBean
(
request
,
ApiForm
.
class
,
true
);
ApiUtils
.
DEBUG
=
!
ApiUtils
.
DEBUG
;
return
new
ApiResp
(
from
).
setData
(
ApiUtils
.
DEBUG
);
}
}
api-server/src/main/java/com/zq/api/form/ApiForm.java
View file @
e67bc01a
...
@@ -37,6 +37,8 @@ public class ApiForm {
...
@@ -37,6 +37,8 @@ public class ApiForm {
private
String
nonce
;
// 随机字串(建议使用UUID)
private
String
nonce
;
// 随机字串(建议使用UUID)
private
String
version
;
// 接口版本
private
String
version
;
// 接口版本
private
String
apiNo
;
// 接口码
private
String
apiNo
;
// 接口码
private
Integer
type
;
// 1-app;2-api,内部定
private
String
clientType
;
// 客户端类型 xcx-小程序,H5,api
private
String
bizContent
;
// 请求业务参数
private
String
bizContent
;
// 请求业务参数
private
JSONObject
bizContentJson
;
// 请求业务的json对象
private
JSONObject
bizContentJson
;
// 请求业务的json对象
private
MultipartFile
file
;
// 上传文件用
private
MultipartFile
file
;
// 上传文件用
...
@@ -44,12 +46,19 @@ public class ApiForm {
...
@@ -44,12 +46,19 @@ public class ApiForm {
public
boolean
parseBizContent
()
{
public
boolean
parseBizContent
()
{
try
{
try
{
if
(
type
==
1
)
{
// API参数是否加密
// API参数是否加密
boolean
flag
=
ConfigCache
.
getValueToBoolean
(
"API.PARAM.ENCRYPT"
);
boolean
flag
=
ConfigCache
.
getValueToBoolean
(
"API.PARAM.ENCRYPT"
);
if
(
StrUtil
.
isNotBlank
(
bizContent
)
&&
flag
)
{
if
(
StrUtil
.
isNotBlank
(
bizContent
)
&&
flag
)
{
bizContent
=
ApiUtils
.
decode
(
bizContent
);
bizContent
=
ApiUtils
.
decode
(
bizContent
,
""
);
}
}
if
(
StrUtil
.
isBlank
(
bizContent
))
{
}
else
{
if
(
StrUtil
.
isNotBlank
(
bizContent
))
{
bizContent
=
ApiUtils
.
decode
(
bizContent
,
"BASE64"
);
}
}
if
(
bizContent
==
null
)
{
bizContent
=
""
;
bizContent
=
""
;
}
}
bizContentJson
=
JSON
.
parseObject
(
bizContent
);
bizContentJson
=
JSON
.
parseObject
(
bizContent
);
...
@@ -148,8 +157,9 @@ public class ApiForm {
...
@@ -148,8 +157,9 @@ public class ApiForm {
public
TreeMap
<
String
,
String
>
getSignTreeMap
()
{
public
TreeMap
<
String
,
String
>
getSignTreeMap
()
{
TreeMap
<
String
,
String
>
treeMap
=
new
TreeMap
<>();
TreeMap
<
String
,
String
>
treeMap
=
new
TreeMap
<>();
treeMap
.
put
(
"appId"
,
this
.
appId
);
treeMap
.
put
(
"apiNo"
,
this
.
apiNo
);
treeMap
.
put
(
"timestamp"
,
this
.
timestamp
);
treeMap
.
put
(
"timestamp"
,
this
.
timestamp
);
treeMap
.
put
(
"nonce"
,
this
.
nonce
);
treeMap
.
put
(
"method"
,
this
.
method
);
treeMap
.
put
(
"method"
,
this
.
method
);
treeMap
.
put
(
"version"
,
this
.
version
);
treeMap
.
put
(
"version"
,
this
.
version
);
String
bizContent
=
StrUtil
.
isBlank
(
this
.
bizContent
)
?
""
:
this
.
bizContent
;
String
bizContent
=
StrUtil
.
isBlank
(
this
.
bizContent
)
?
""
:
this
.
bizContent
;
...
@@ -157,4 +167,17 @@ public class ApiForm {
...
@@ -157,4 +167,17 @@ public class ApiForm {
return
treeMap
;
return
treeMap
;
}
}
public
String
getSignStr
(
String
key
)
{
TreeMap
<
String
,
String
>
treeMap
=
getSignTreeMap
();
// 原始请求串
StringBuilder
src
=
new
StringBuilder
();
for
(
Map
.
Entry
<
String
,
String
>
entry
:
treeMap
.
entrySet
())
{
src
.
append
(
entry
.
getKey
()).
append
(
"="
).
append
(
entry
.
getValue
()).
append
(
"&"
);
}
src
.
append
(
"key="
).
append
(
key
);
return
src
.
toString
();
}
}
}
api-server/src/main/java/com/zq/api/service/ApiService.java
View file @
e67bc01a
package
com
.
zq
.
api
.
service
;
package
com
.
zq
.
api
.
service
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.date.DateUtil
;
import
com.zq.api.config.ConfigCache
;
import
cn.hutool.core.util.StrUtil
;
import
com.zq.api.constant.ApiCodeEnum
;
import
com.zq.api.dao.ApiLogDao
;
import
com.zq.api.dao.ApiLogDao
;
import
com.zq.api.entity.ApiLog
;
import
com.zq.api.entity.ApiLog
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiResp
;
import
com.zq.api.form.ApiResp
;
import
com.zq.api.utils.ApiUtils
;
import
com.zq.api.utils.ApiUtils
;
import
com.zq.api.utils.ReflectionUtils
;
import
com.zq.api.utils.ReflectionUtils
;
import
com.zq.common.config.redis.BaseCacheKeys
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.vo.ApiTokenVo
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.scheduling.annotation.Async
;
...
@@ -16,6 +18,7 @@ import org.springframework.stereotype.Service;
...
@@ -16,6 +18,7 @@ import org.springframework.stereotype.Service;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
@Slf4j
@Slf4j
...
@@ -24,6 +27,10 @@ import java.util.List;
...
@@ -24,6 +27,10 @@ import java.util.List;
public
class
ApiService
{
public
class
ApiService
{
private
final
ApiLogDao
apiLogDao
;
private
final
ApiLogDao
apiLogDao
;
private
final
RedisUtils
redisUtils
;
// 允许用户未登录状态下执行的方法名
private
final
String
[]
allowMethod
=
{
"getApiToken"
};
private
static
final
List
<
String
>
METHOD_LIST
;
private
static
final
List
<
String
>
METHOD_LIST
;
...
@@ -48,20 +55,42 @@ public class ApiService {
...
@@ -48,20 +55,42 @@ public class ApiService {
return
methodList
;
return
methodList
;
}
}
/**
* 身份验证
*
* @param form
* @return
*/
public
ApiResp
auth
(
ApiForm
form
,
String
token
)
{
boolean
contains
=
Arrays
.
asList
(
allowMethod
).
contains
(
form
.
getMethod
());
if
(
contains
)
{
return
ApiUtils
.
getSuccessResp
(
form
);
}
else
if
(
StrUtil
.
isBlank
(
token
))
{
return
ApiUtils
.
getLoginValidError
(
form
);
}
// 验证认证信息
ApiTokenVo
tokenVo
=
redisUtils
.
getObj
(
BaseCacheKeys
.
PREFIX
+
"ApiToken."
+
token
,
ApiTokenVo
.
class
);
if
(
tokenVo
==
null
)
{
return
ApiUtils
.
getLoginValidError
(
form
);
}
// 验证签名
String
sign
=
ApiUtils
.
getSign
(
form
.
getSignStr
(
tokenVo
.
getSessionKey
()
==
null
?
""
:
tokenVo
.
getSessionKey
()));
if
(!
sign
.
equals
(
form
.
getSign
()))
{
return
ApiUtils
.
getCheckSignValidError
(
form
);
}
form
.
setUserId
(
tokenVo
.
getUserId
());
form
.
setApiTokenVo
(
tokenVo
);
return
ApiUtils
.
getSuccessResp
(
form
);
}
public
ApiResp
action
(
ApiForm
form
)
throws
Exception
{
public
ApiResp
action
(
ApiForm
form
)
throws
Exception
{
if
(!
METHOD_LIST
.
contains
(
form
.
getMethod
()))
{
if
(!
METHOD_LIST
.
contains
(
form
.
getMethod
()))
{
return
ApiUtils
.
getMethodError
(
form
);
return
ApiUtils
.
getMethodError
(
form
);
}
}
// 签名验证标识
boolean
validFlag
=
ConfigCache
.
getValueToBoolean
(
"API.SIGN.VALID"
);
IApiLogic
apiLogic
=
getApiLogic
(
form
);
IApiLogic
apiLogic
=
getApiLogic
(
form
);
if
(
validFlag
)
{
// 验证签名
ApiResp
validResp
=
apiLogic
.
signValid
(
form
);
if
(!
validResp
.
getCode
().
equals
(
ApiCodeEnum
.
SUCCESS
.
code
()))
{
return
validResp
;
}
}
// 调用接口方法,利用反射更简洁
// 调用接口方法,利用反射更简洁
return
(
ApiResp
)
ReflectionUtils
.
invokeMethod
(
apiLogic
,
form
.
getMethod
(),
new
Class
<?>[]{
ApiForm
.
class
},
new
Object
[]{
form
});
return
(
ApiResp
)
ReflectionUtils
.
invokeMethod
(
apiLogic
,
form
.
getMethod
(),
new
Class
<?>[]{
ApiForm
.
class
},
new
Object
[]{
form
});
...
...
api-server/src/main/java/com/zq/api/service/AppService.java
0 → 100644
View file @
e67bc01a
package
com
.
zq
.
api
.
service
;
import
cn.hutool.core.date.DateUtil
;
import
com.zq.api.config.ConfigCache
;
import
com.zq.api.constant.ApiCodeEnum
;
import
com.zq.api.dao.ApiLogDao
;
import
com.zq.api.entity.ApiLog
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiResp
;
import
com.zq.api.utils.ApiUtils
;
import
com.zq.api.utils.ReflectionUtils
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Service
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author wilmiam
* @since 2022/5/30 12:33
*/
@Slf4j
@Service
@RequiredArgsConstructor
public
class
AppService
{
private
final
ApiLogDao
apiLogDao
;
private
static
final
List
<
String
>
METHOD_LIST
;
static
{
METHOD_LIST
=
methodList
();
}
public
IApiLogic
getApiLogic
(
ApiForm
form
)
{
IApiLogic
apiLogic
=
ApiUtils
.
getApiLogic
(
form
);
return
apiLogic
;
}
public
static
List
<
String
>
methodList
()
{
List
<
String
>
methodList
=
new
ArrayList
<>();
Method
[]
methods
=
IApiLogic
.
class
.
getMethods
();
for
(
Method
method
:
methods
)
{
Class
<?>[]
params
=
method
.
getParameterTypes
();
if
(
params
.
length
==
1
&&
(
params
[
0
]
==
ApiForm
.
class
))
{
methodList
.
add
(
method
.
getName
());
}
}
return
methodList
;
}
public
ApiResp
action
(
ApiForm
form
)
throws
Exception
{
if
(!
METHOD_LIST
.
contains
(
form
.
getMethod
()))
{
return
ApiUtils
.
getMethodError
(
form
);
}
// 签名验证标识
boolean
validFlag
=
ConfigCache
.
getValueToBoolean
(
"API.SIGN.VALID"
);
IApiLogic
apiLogic
=
getApiLogic
(
form
);
if
(
validFlag
)
{
// 验证签名
ApiResp
validResp
=
apiLogic
.
signValid
(
form
);
if
(!
validResp
.
getCode
().
equals
(
ApiCodeEnum
.
SUCCESS
.
code
()))
{
return
validResp
;
}
}
// 调用接口方法,利用反射更简洁
return
(
ApiResp
)
ReflectionUtils
.
invokeMethod
(
apiLogic
,
form
.
getMethod
(),
new
Class
<?>[]{
ApiForm
.
class
},
new
Object
[]{
form
});
}
@Async
public
void
addLog
(
ApiForm
form
,
String
ip
,
String
logType
,
String
respMsg
,
String
errorInfo
,
Long
timeCost
)
{
apiLogDao
.
insert
(
ApiLog
.
builder
()
.
appId
(
form
.
getAppId
())
.
userId
(
form
.
getUserId
())
.
method
(
form
.
getMethod
())
.
version
(
form
.
getVersion
())
.
bizContent
(
form
.
getBizContent
())
.
ip
(
ip
)
.
logType
(
logType
)
.
respMsg
(
respMsg
)
.
stackTrace
(
errorInfo
)
.
timeCost
(
timeCost
)
.
createTime
(
DateUtil
.
date
().
toJdkDate
())
.
build
());
}
}
api-server/src/main/java/com/zq/api/service/impl/BaseApiLogic.java
View file @
e67bc01a
...
@@ -27,7 +27,7 @@ public abstract class BaseApiLogic implements IApiLogic {
...
@@ -27,7 +27,7 @@ public abstract class BaseApiLogic implements IApiLogic {
return
ApiUtils
.
getCheckSignValidError
(
form
);
return
ApiUtils
.
getCheckSignValidError
(
form
);
}
}
String
serverSign
=
ApiUtils
.
getSign
(
form
.
getSign
TreeMap
(
));
String
serverSign
=
ApiUtils
.
getSign
(
form
.
getSign
Str
(
""
));
if
(!
serverSign
.
equals
(
form
.
getSign
()))
{
if
(!
serverSign
.
equals
(
form
.
getSign
()))
{
return
ApiUtils
.
getCheckSignValidError
(
form
);
return
ApiUtils
.
getCheckSignValidError
(
form
);
}
}
...
...
api-server/src/main/java/com/zq/api/utils/ApiUtils.java
View file @
e67bc01a
...
@@ -13,12 +13,8 @@ import com.zq.common.vo.ResultVo;
...
@@ -13,12 +13,8 @@ import com.zq.common.vo.ResultVo;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.stereotype.Component
;
import
org.springframework.stereotype.Component
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLDecoder
;
import
java.net.URLEncoder
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.TreeMap
;
/**
/**
* @author wilmiam
* @author wilmiam
...
@@ -172,11 +168,17 @@ public class ApiUtils {
...
@@ -172,11 +168,17 @@ public class ApiUtils {
*
*
* @param params
* @param params
* @return
* @return
* @throws UnsupportedEncodingException
*/
*/
public
static
String
decode
(
String
params
)
throws
UnsupportedEncodingException
{
public
static
String
decode
(
String
params
,
String
encryptType
)
{
params
=
URLDecoder
.
decode
(
params
,
"utf-8"
);
if
(
StringUtils
.
isBlank
(
params
))
{
return
""
;
}
params
=
EncryptUtils
.
urlDecode
(
params
,
"UTF-8"
);
if
(
"RSA"
.
equals
(
encryptType
))
{
params
=
EncryptUtils
.
rsaDecodeByPrivateKey
(
params
,
RsaUtils
.
privateKey
);
params
=
EncryptUtils
.
rsaDecodeByPrivateKey
(
params
,
RsaUtils
.
privateKey
);
}
else
{
params
=
EncryptUtils
.
base64Decode
(
params
);
}
return
params
;
return
params
;
}
}
...
@@ -187,14 +189,17 @@ public class ApiUtils {
...
@@ -187,14 +189,17 @@ public class ApiUtils {
*
*
* @param params
* @param params
* @return
* @return
* @throws UnsupportedEncodingException
*/
*/
public
static
String
encode
(
String
params
)
throws
UnsupportedEncodingException
{
public
static
String
encode
(
String
params
,
String
encryptType
)
{
params
=
EncryptUtils
.
rsaDecodeByPrivateKey
(
params
,
RsaUtils
.
publicKey
);
if
(
StringUtils
.
isBlank
(
params
))
{
if
(
StringUtils
.
isBlank
(
params
))
{
return
""
;
return
""
;
}
}
params
=
URLEncoder
.
encode
(
params
,
"utf-8"
);
if
(
"RSA"
.
equals
(
encryptType
))
{
params
=
EncryptUtils
.
rsaDecodeByPrivateKey
(
params
,
RsaUtils
.
publicKey
);
}
else
{
params
=
EncryptUtils
.
base64Decode
(
params
);
}
params
=
EncryptUtils
.
urlEncode
(
params
,
"UTF-8"
);
return
params
;
return
params
;
}
}
...
@@ -203,16 +208,11 @@ public class ApiUtils {
...
@@ -203,16 +208,11 @@ public class ApiUtils {
* <p>
* <p>
* 2017年3月15日 下午3:14:27
* 2017年3月15日 下午3:14:27
*
*
* @param
paramMaps
* @param
content
* @return
* @return
*/
*/
public
static
String
getSign
(
TreeMap
<
String
,
String
>
paramMaps
)
{
public
static
String
getSign
(
String
content
)
{
// 原始请求串
return
MD5
.
create
().
digestHex
(
content
).
toUpperCase
();
StringBuilder
src
=
new
StringBuilder
();
for
(
Map
.
Entry
<
String
,
String
>
entry
:
paramMaps
.
entrySet
())
{
src
.
append
(
entry
.
getKey
()).
append
(
"="
).
append
(
entry
.
getValue
()).
append
(
"&"
);
}
return
MD5
.
create
().
digestHex
(
src
.
toString
());
}
}
}
}
xxx-common-utils/src/main/java/com/zq/common/constant/Cloud
Constant.java
→
logging-server/src/main/java/com/zq/logging/constant/
Constant.java
View file @
e67bc01a
...
@@ -13,7 +13,7 @@
...
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* See the License for the specific language governing permissions and
* limitations under the License.
* limitations under the License.
*/
*/
package
com
.
zq
.
common
.
constant
;
package
com
.
zq
.
logging
.
constant
;
/**
/**
* 常用静态常量
* 常用静态常量
...
@@ -21,7 +21,7 @@ package com.zq.common.constant;
...
@@ -21,7 +21,7 @@ package com.zq.common.constant;
* @author Zheng Jie
* @author Zheng Jie
* @date 2018-12-26
* @date 2018-12-26
*/
*/
public
class
C
loudC
onstant
{
public
class
Constant
{
/**
/**
* 用于IP定位转换
* 用于IP定位转换
...
...
logging-server/src/main/java/com/zq/logging/utils/RequestUtils.java
View file @
e67bc01a
...
@@ -3,8 +3,8 @@ package com.zq.logging.utils;
...
@@ -3,8 +3,8 @@ package com.zq.logging.utils;
import
cn.hutool.http.HttpUtil
;
import
cn.hutool.http.HttpUtil
;
import
cn.hutool.json.JSONUtil
;
import
cn.hutool.json.JSONUtil
;
import
com.zq.common.config.base.SpringContextHolder
;
import
com.zq.common.config.base.SpringContextHolder
;
import
com.zq.common.constant.CloudConstant
;
import
com.zq.logging.config.AdminProperties
;
import
com.zq.logging.config.AdminProperties
;
import
com.zq.logging.constant.Constant
;
import
net.dreamlu.mica.ip2region.core.Ip2regionSearcher
;
import
net.dreamlu.mica.ip2region.core.Ip2regionSearcher
;
import
net.dreamlu.mica.ip2region.core.IpInfo
;
import
net.dreamlu.mica.ip2region.core.IpInfo
;
import
nl.basjes.parse.useragent.UserAgent
;
import
nl.basjes.parse.useragent.UserAgent
;
...
@@ -46,7 +46,7 @@ public class RequestUtils {
...
@@ -46,7 +46,7 @@ public class RequestUtils {
* 根据ip获取详细地址
* 根据ip获取详细地址
*/
*/
public
static
String
getHttpCityInfo
(
String
ip
)
{
public
static
String
getHttpCityInfo
(
String
ip
)
{
String
api
=
String
.
format
(
C
loudC
onstant
.
Url
.
IP_URL
,
ip
);
String
api
=
String
.
format
(
Constant
.
Url
.
IP_URL
,
ip
);
cn
.
hutool
.
json
.
JSONObject
object
=
JSONUtil
.
parseObj
(
HttpUtil
.
get
(
api
));
cn
.
hutool
.
json
.
JSONObject
object
=
JSONUtil
.
parseObj
(
HttpUtil
.
get
(
api
));
return
object
.
get
(
"addr"
,
String
.
class
);
return
object
.
get
(
"addr"
,
String
.
class
);
}
}
...
...
user-server/src/main/java/com/zq/user/config/SpringSecurityConfig.java
View file @
e67bc01a
...
@@ -18,7 +18,6 @@ package com.zq.user.config;
...
@@ -18,7 +18,6 @@ package com.zq.user.config;
import
com.zq.common.annotation.AnonymousAccess
;
import
com.zq.common.annotation.AnonymousAccess
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
com.zq.common.utils.RequestMethodEnum
;
import
com.zq.common.utils.RequestMethodEnum
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContext
;
...
...
user-server/src/main/java/com/zq/user/config/TokenConfigurer.java
View file @
e67bc01a
...
@@ -17,7 +17,6 @@ package com.zq.user.config;
...
@@ -17,7 +17,6 @@ package com.zq.user.config;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
lombok.RequiredArgsConstructor
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
...
...
user-server/src/main/java/com/zq/user/config/TokenFilter.java
View file @
e67bc01a
...
@@ -19,7 +19,6 @@ import cn.hutool.core.util.StrUtil;
...
@@ -19,7 +19,6 @@ import cn.hutool.core.util.StrUtil;
import
com.zq.common.config.redis.BaseCacheKeys
;
import
com.zq.common.config.redis.BaseCacheKeys
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.redis.RedisUtils
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.SecurityProperties
;
import
com.zq.common.config.security.TokenProvider
;
import
com.zq.common.context.ContextUtils
;
import
com.zq.common.context.ContextUtils
;
import
com.zq.common.vo.OnlineUserDto
;
import
com.zq.common.vo.OnlineUserDto
;
import
io.jsonwebtoken.ExpiredJwtException
;
import
io.jsonwebtoken.ExpiredJwtException
;
...
...
user-server/src/main/java/com/zq/user/config/TokenProvider.java
View file @
e67bc01a
This diff is collapsed.
Click to expand it.
xxx-common-utils/src/main/java/com/zq/common/config/base/UnifiedExceptionHandler.java
View file @
e67bc01a
package
com
.
zq
.
common
.
config
.
base
;
package
com
.
zq
.
common
.
config
.
base
;
import
com.zq.common.constant.FeignHeader
;
import
com.zq.common.constant.SystemName
;
import
com.zq.common.exception.BusinessException
;
import
com.zq.common.exception.BusinessException
;
import
com.zq.common.utils.ThrowableUtil
;
import
com.zq.common.utils.ThrowableUtil
;
import
com.zq.common.vo.ResultVo
;
import
com.zq.common.vo.ResultVo
;
...
@@ -94,8 +96,9 @@ public class UnifiedExceptionHandler {
...
@@ -94,8 +96,9 @@ public class UnifiedExceptionHandler {
@ExceptionHandler
(
DataAccessException
.
class
)
@ExceptionHandler
(
DataAccessException
.
class
)
public
ResultVo
handleDataAccessException
(
DataAccessException
ex
,
HttpServletRequest
request
)
{
public
ResultVo
handleDataAccessException
(
DataAccessException
ex
,
HttpServletRequest
request
)
{
log
.
error
(
">> 访问数据失败 "
+
request
.
getRequestURI
(),
ex
);
log
.
error
(
">> 访问数据失败 "
+
request
.
getRequestURI
(),
ex
);
String
header
=
request
.
getHeader
(
FeignHeader
.
SERVER_NAME
);
String
error
=
"服务器繁忙"
;
String
error
=
"服务器繁忙"
;
if
(
request
.
getRequestURI
().
contains
(
"/app/"
))
{
if
(
StringUtils
.
isNotBlank
(
header
)
&&
SystemName
.
API
.
equals
(
header
))
{
error
=
ThrowableUtil
.
getStackTrace
(
ex
);
error
=
ThrowableUtil
.
getStackTrace
(
ex
);
}
}
return
ResultVo
.
fail
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
error
);
return
ResultVo
.
fail
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
error
);
...
@@ -104,8 +107,9 @@ public class UnifiedExceptionHandler {
...
@@ -104,8 +107,9 @@ public class UnifiedExceptionHandler {
@ExceptionHandler
(
value
=
Exception
.
class
)
@ExceptionHandler
(
value
=
Exception
.
class
)
public
ResultVo
defaultErrorHandler
(
Exception
ex
,
HttpServletRequest
request
)
{
public
ResultVo
defaultErrorHandler
(
Exception
ex
,
HttpServletRequest
request
)
{
log
.
error
(
">> 服务器内部错误 "
+
request
.
getRequestURI
(),
ex
);
log
.
error
(
">> 服务器内部错误 "
+
request
.
getRequestURI
(),
ex
);
String
header
=
request
.
getHeader
(
FeignHeader
.
SERVER_NAME
);
String
error
=
"服务器繁忙"
;
String
error
=
"服务器繁忙"
;
if
(
request
.
getRequestURI
().
contains
(
"/app/"
))
{
if
(
StringUtils
.
isNotBlank
(
header
)
&&
SystemName
.
API
.
equals
(
header
))
{
error
=
ThrowableUtil
.
getStackTrace
(
ex
);
error
=
ThrowableUtil
.
getStackTrace
(
ex
);
}
}
return
ResultVo
.
fail
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
error
);
return
ResultVo
.
fail
(
HttpStatus
.
INTERNAL_SERVER_ERROR
.
value
(),
error
);
...
...
xxx-common-utils/src/main/java/com/zq/common/config/security/TokenProvider.java
deleted
100644 → 0
View file @
4809b2b9
package
com
.
zq
.
common
.
config
.
security
;
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import
cn.hutool.core.date.DateField
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.zq.common.config.redis.RedisUtils
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SignatureAlgorithm
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.authority.SimpleGrantedAuthority
;
import
org.springframework.security.core.userdetails.User
;
import
org.springframework.stereotype.Component
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.xml.bind.DatatypeConverter
;
import
java.security.Key
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Date
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
/**
* @author /
*/
@Slf4j
@Component
@RequiredArgsConstructor
public
class
TokenProvider
implements
InitializingBean
{
private
final
RedisUtils
redisUtils
;
private
final
SecurityProperties
properties
;
public
static
final
String
AUTHORITIES_KEY
=
"auth"
;
private
static
Key
key
;
private
static
SignatureAlgorithm
signatureAlgorithm
;
@Override
public
void
afterPropertiesSet
()
{
signatureAlgorithm
=
SignatureAlgorithm
.
HS512
;
byte
[]
keyBytes
=
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
());
key
=
new
SecretKeySpec
(
keyBytes
,
signatureAlgorithm
.
getJcaName
());
}
public
static
String
createToken
(
Authentication
authentication
)
{
String
authorities
=
authentication
.
getAuthorities
().
stream
()
.
map
(
GrantedAuthority:
:
getAuthority
)
.
collect
(
Collectors
.
joining
(
","
));
return
Jwts
.
builder
()
.
setSubject
(
authentication
.
getName
())
.
claim
(
AUTHORITIES_KEY
,
authorities
)
.
signWith
(
signatureAlgorithm
,
key
)
// 加入ID确保生成的 Token 都不一致
.
setId
(
IdUtil
.
simpleUUID
())
.
compact
();
}
public
Claims
getClaims
(
String
token
)
{
return
Jwts
.
parser
()
.
setSigningKey
(
DatatypeConverter
.
parseBase64Binary
(
properties
.
getBase64Secret
()))
.
parseClaimsJws
(
token
)
.
getBody
();
}
public
Authentication
getAuthentication
(
String
token
)
{
Claims
claims
=
getClaims
(
token
);
// fix bug: 当前用户如果没有任何权限时,在输入用户名后,刷新验证码会抛IllegalArgumentException
Object
authoritiesStr
=
claims
.
get
(
AUTHORITIES_KEY
);
Collection
<?
extends
GrantedAuthority
>
authorities
=
ObjectUtil
.
isNotEmpty
(
authoritiesStr
)
?
Arrays
.
stream
(
authoritiesStr
.
toString
().
split
(
","
))
.
map
(
SimpleGrantedAuthority:
:
new
)
.
collect
(
Collectors
.
toList
())
:
Collections
.
emptyList
();
User
principal
=
new
User
(
claims
.
getSubject
(),
"******"
,
authorities
);
return
new
UsernamePasswordAuthenticationToken
(
principal
,
token
,
authorities
);
}
/**
* @param token 需要检查的token
*/
public
void
checkRenewal
(
String
token
)
{
// 判断是否续期token,计算token的过期时间
long
time
=
redisUtils
.
getExpire
(
properties
.
getOnlineKey
()
+
token
)
*
1000
;
Date
expireDate
=
DateUtil
.
offset
(
new
Date
(),
DateField
.
MILLISECOND
,
(
int
)
time
);
// 判断当前时间与过期时间的时间差
long
differ
=
expireDate
.
getTime
()
-
System
.
currentTimeMillis
();
// 如果在续期检查的范围内,则续期
if
(
differ
<=
properties
.
getDetect
())
{
long
renew
=
time
+
properties
.
getRenew
();
redisUtils
.
expire
(
properties
.
getOnlineKey
()
+
token
,
renew
,
TimeUnit
.
MILLISECONDS
);
}
}
public
String
getToken
(
HttpServletRequest
request
)
{
String
bearerToken
=
request
.
getHeader
(
properties
.
getHeader
());
if
(
StringUtils
.
isBlank
(
bearerToken
))
{
return
null
;
}
if
(
bearerToken
.
startsWith
(
properties
.
getTokenStartWith
()))
{
// 去掉令牌前缀
return
bearerToken
.
replace
(
properties
.
getTokenStartWith
(),
""
);
}
else
{
log
.
debug
(
"非法Token:{}"
,
bearerToken
);
}
return
null
;
}
}
xxx-common-utils/src/main/java/com/zq/common/constant/FeignHeader.java
0 → 100644
View file @
e67bc01a
package
com
.
zq
.
common
.
constant
;
/**
* feign要添加的请求头
*
* @author wilmiam
* @since 2021/9/6 9:43
*/
public
class
FeignHeader
{
/**
* feign添加服务名的请求头字段
*/
public
static
final
String
SERVER_NAME
=
"X-Server-Name"
;
/**
* feign添加api-token的请求头字段
*/
public
static
final
String
API_TOKEN
=
"X-Api-Token"
;
}
xxx-common-utils/src/main/java/com/zq/common/constant/SystemName.java
0 → 100644
View file @
e67bc01a
package
com
.
zq
.
common
.
constant
;
/**
* @author wilmiam
* @since 2021-09-06 09:16
*/
public
class
SystemName
{
public
static
final
String
ADMIN
=
"admin"
;
public
static
final
String
API
=
"api"
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment