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
e3b3c416
Commit
e3b3c416
authored
May 28, 2021
by
袁伟铭
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.0.0
parent
8586f14f
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
190 additions
and
6 deletions
+190
-6
api-server/src/main/java/com/zq/api/controller/ApiController.java
+7
-0
api-server/src/main/java/com/zq/api/form/ApiForm.java
+11
-6
api-server/src/main/java/com/zq/api/utils/ApiUtils.java
+11
-0
common-utils/src/main/java/com/zq/common/utils/WxUserSigUtils.java
+161
-0
No files found.
api-server/src/main/java/com/zq/api/controller/ApiController.java
View file @
e3b3c416
...
@@ -4,6 +4,7 @@ import cn.hutool.core.exceptions.ExceptionUtil;
...
@@ -4,6 +4,7 @@ import cn.hutool.core.exceptions.ExceptionUtil;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.extra.servlet.ServletUtil
;
import
cn.hutool.extra.servlet.ServletUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.zq.api.constant.ApiCodeEnum
;
import
com.zq.api.constant.ApiCodeEnum
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiForm
;
import
com.zq.api.form.ApiResp
;
import
com.zq.api.form.ApiResp
;
...
@@ -43,6 +44,12 @@ public class ApiController {
...
@@ -43,6 +44,12 @@ public class ApiController {
long
start
=
System
.
currentTimeMillis
();
long
start
=
System
.
currentTimeMillis
();
ApiForm
form
=
ServletUtil
.
toBean
(
request
,
ApiForm
.
class
,
true
);
ApiForm
form
=
ServletUtil
.
toBean
(
request
,
ApiForm
.
class
,
true
);
try
{
JSONObject
jsonObject
=
JSON
.
parseObject
(
form
.
getBizContent
());
form
.
setBizContentJson
(
jsonObject
);
}
catch
(
Exception
e
)
{
return
ApiUtils
.
getParamError
(
form
);
}
// 不处理Request Method:OPTIONS的请求
// 不处理Request Method:OPTIONS的请求
if
(
request
.
getMethod
().
equals
(
"OPTIONS"
))
{
if
(
request
.
getMethod
().
equals
(
"OPTIONS"
))
{
...
...
api-server/src/main/java/com/zq/api/form/ApiForm.java
View file @
e3b3c416
...
@@ -38,9 +38,14 @@ public class ApiForm {
...
@@ -38,9 +38,14 @@ public class ApiForm {
private
String
version
;
// 接口版本
private
String
version
;
// 接口版本
private
String
apiNo
;
// 接口码
private
String
apiNo
;
// 接口码
private
String
bizContent
;
// 请求业务参数
private
String
bizContent
;
// 请求业务参数
private
JSONObject
bizContentJson
;
// 请求业务的json对象
private
ApiTokenVo
apiTokenVo
;
private
ApiTokenVo
apiTokenVo
;
public
JSONObject
getBizContentJson
()
{
public
JSONObject
getContentJson
()
{
if
(
bizContentJson
!=
null
)
{
return
bizContentJson
;
}
JSONObject
object
=
JSON
.
parseObject
(
bizContent
);
JSONObject
object
=
JSON
.
parseObject
(
bizContent
);
if
(
object
==
null
)
{
if
(
object
==
null
)
{
return
new
JSONObject
();
return
new
JSONObject
();
...
@@ -97,7 +102,7 @@ public class ApiForm {
...
@@ -97,7 +102,7 @@ public class ApiForm {
* @return
* @return
*/
*/
public
String
get
(
String
key
)
{
public
String
get
(
String
key
)
{
return
get
Biz
ContentJson
().
getString
(
key
);
return
getContentJson
().
getString
(
key
);
}
}
/**
/**
...
@@ -107,7 +112,7 @@ public class ApiForm {
...
@@ -107,7 +112,7 @@ public class ApiForm {
* @return
* @return
*/
*/
public
Boolean
getBoolean
(
String
key
)
{
public
Boolean
getBoolean
(
String
key
)
{
return
get
Biz
ContentJson
().
getBoolean
(
key
);
return
getContentJson
().
getBoolean
(
key
);
}
}
/**
/**
...
@@ -119,7 +124,7 @@ public class ApiForm {
...
@@ -119,7 +124,7 @@ public class ApiForm {
* @return
* @return
*/
*/
public
JSONObject
getJSONObject
(
String
key
)
{
public
JSONObject
getJSONObject
(
String
key
)
{
return
get
Biz
ContentJson
().
getJSONObject
(
key
);
return
getContentJson
().
getJSONObject
(
key
);
}
}
/**
/**
...
@@ -131,7 +136,7 @@ public class ApiForm {
...
@@ -131,7 +136,7 @@ public class ApiForm {
* @return
* @return
*/
*/
public
JSONArray
getJSONArray
(
String
key
)
{
public
JSONArray
getJSONArray
(
String
key
)
{
return
get
Biz
ContentJson
().
getJSONArray
(
key
);
return
getContentJson
().
getJSONArray
(
key
);
}
}
/**
/**
...
@@ -158,7 +163,7 @@ public class ApiForm {
...
@@ -158,7 +163,7 @@ public class ApiForm {
* @return
* @return
*/
*/
public
Map
<
String
,
Object
>
getParamsMap
(
boolean
isSetUserId
,
String
key
)
{
public
Map
<
String
,
Object
>
getParamsMap
(
boolean
isSetUserId
,
String
key
)
{
JSONObject
json
=
get
Biz
ContentJson
();
JSONObject
json
=
getContentJson
();
Map
<
String
,
Object
>
innerMap
=
json
.
getInnerMap
();
Map
<
String
,
Object
>
innerMap
=
json
.
getInnerMap
();
innerMap
.
put
(
"token"
,
getToken
());
innerMap
.
put
(
"token"
,
getToken
());
if
(
isSetUserId
)
{
if
(
isSetUserId
)
{
...
...
api-server/src/main/java/com/zq/api/utils/ApiUtils.java
View file @
e3b3c416
...
@@ -117,6 +117,17 @@ public class ApiUtils {
...
@@ -117,6 +117,17 @@ public class ApiUtils {
return
new
ApiResp
(
form
,
ApiCodeEnum
.
METHOD_HANDLER_ERROR
);
return
new
ApiResp
(
form
,
ApiCodeEnum
.
METHOD_HANDLER_ERROR
);
}
}
/**
* 传递参数异常
* <p>
* 2016年9月29日 上午11:44:38
*
* @return
*/
public
static
ApiResp
getParamError
(
ApiForm
form
)
{
return
new
ApiResp
(
form
,
ApiCodeEnum
.
PARAM_ERROR
);
}
public
static
ApiResp
toApiResp
(
ApiForm
form
,
ResultVo
resultVo
)
{
public
static
ApiResp
toApiResp
(
ApiForm
form
,
ResultVo
resultVo
)
{
ApiResp
apiResp
=
new
ApiResp
(
form
);
ApiResp
apiResp
=
new
ApiResp
(
form
);
if
(
resultVo
.
isSuccess
())
{
if
(
resultVo
.
isSuccess
())
{
...
...
common-utils/src/main/java/com/zq/common/utils/WxUserSigUtils.java
0 → 100644
View file @
e3b3c416
package
com
.
zq
.
common
.
utils
;
import
com.alibaba.fastjson.JSONException
;
import
com.alibaba.fastjson.JSONObject
;
import
org.apache.commons.lang3.StringUtils
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.nio.charset.StandardCharsets
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Arrays
;
import
java.util.Base64
;
import
java.util.zip.Deflater
;
public
class
WxUserSigUtils
{
/**
* 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
* <p>
* 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc ) 创建应用,即可看到 SDKAppId,
* 它是腾讯云用于区分客户的唯一标识。
*/
public
static
final
int
SDKAPPID
=
1400447523
;
/**
* 签名过期时间,建议不要设置的过短
* <p>
* 时间单位:秒
* 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
*/
private
static
final
int
EXPIRETIME
=
604800
;
/**
* 计算签名用的加密密钥,获取步骤如下:
* <p>
* step1. 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc ) ,如果还没有应用就创建一个,
* step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
* step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
* <p>
* 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
*/
private
static
final
String
SECRETKEY
=
"da4138b5ed488dbb93de2b2b0206ce9b57629be51d92d73a8c71c710c5bfb5f0"
;
/**
* 计算 UserSig 签名
* <p>
* 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。
*
* @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
* <p>
* 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
* <p>
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
* <p>
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
*/
public
static
String
genUserSig
(
String
userId
,
Integer
expireTime
)
{
return
GenTLSSignature
(
SDKAPPID
,
userId
,
expireTime
==
null
?
EXPIRETIME
:
expireTime
,
null
,
SECRETKEY
);
}
/**
* 生成 tls 票据
*
* @param sdkappid 应用的 appid
* @param userId 用户 id
* @param expire 有效期,单位是秒
* @param userbuf 默认填写null
* @param priKeyContent 生成 tls 票据使用的私钥内容
* @return 如果出错,会返回为空,或者有异常打印,成功返回有效的票据
*/
private
static
String
GenTLSSignature
(
long
sdkappid
,
String
userId
,
long
expire
,
byte
[]
userbuf
,
String
priKeyContent
)
{
if
(
StringUtils
.
isEmpty
(
priKeyContent
))
{
return
""
;
}
long
currTime
=
System
.
currentTimeMillis
()
/
1000
;
JSONObject
sigDoc
=
new
JSONObject
();
try
{
sigDoc
.
put
(
"TLS.ver"
,
"2.0"
);
sigDoc
.
put
(
"TLS.identifier"
,
userId
);
sigDoc
.
put
(
"TLS.sdkappid"
,
sdkappid
);
sigDoc
.
put
(
"TLS.expire"
,
expire
);
sigDoc
.
put
(
"TLS.time"
,
currTime
);
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
String
base64UserBuf
=
null
;
if
(
null
!=
userbuf
)
{
base64UserBuf
=
Base64
.
getEncoder
().
encodeToString
(
userbuf
);
try
{
sigDoc
.
put
(
"TLS.userbuf"
,
base64UserBuf
);
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
}
String
sig
=
hmacsha256
(
sdkappid
,
userId
,
currTime
,
expire
,
priKeyContent
,
base64UserBuf
);
if
(
sig
.
length
()
==
0
)
{
return
""
;
}
try
{
sigDoc
.
put
(
"TLS.sig"
,
sig
);
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
Deflater
compressor
=
new
Deflater
();
compressor
.
setInput
(
sigDoc
.
toString
().
getBytes
(
StandardCharsets
.
UTF_8
));
compressor
.
finish
();
byte
[]
compressedBytes
=
new
byte
[
2048
];
int
compressedBytesLength
=
compressor
.
deflate
(
compressedBytes
);
compressor
.
end
();
return
new
String
(
base64EncodeUrl
(
Arrays
.
copyOfRange
(
compressedBytes
,
0
,
compressedBytesLength
)));
}
private
static
String
hmacsha256
(
long
sdkappid
,
String
userId
,
long
currTime
,
long
expire
,
String
priKeyContent
,
String
base64Userbuf
)
{
String
contentToBeSigned
=
"TLS.identifier:"
+
userId
+
"\n"
+
"TLS.sdkappid:"
+
sdkappid
+
"\n"
+
"TLS.time:"
+
currTime
+
"\n"
+
"TLS.expire:"
+
expire
+
"\n"
;
if
(
null
!=
base64Userbuf
)
{
contentToBeSigned
+=
"TLS.userbuf:"
+
base64Userbuf
+
"\n"
;
}
try
{
byte
[]
byteKey
=
priKeyContent
.
getBytes
(
StandardCharsets
.
UTF_8
);
Mac
hmac
=
Mac
.
getInstance
(
"HmacSHA256"
);
SecretKeySpec
keySpec
=
new
SecretKeySpec
(
byteKey
,
"HmacSHA256"
);
hmac
.
init
(
keySpec
);
byte
[]
byteSig
=
hmac
.
doFinal
(
contentToBeSigned
.
getBytes
(
StandardCharsets
.
UTF_8
));
return
new
String
(
Base64
.
getEncoder
().
encode
(
byteSig
));
}
catch
(
NoSuchAlgorithmException
|
InvalidKeyException
e
)
{
return
""
;
}
}
private
static
byte
[]
base64EncodeUrl
(
byte
[]
input
)
{
byte
[]
base64
=
new
String
(
Base64
.
getEncoder
().
encode
(
input
)).
getBytes
();
for
(
int
i
=
0
;
i
<
base64
.
length
;
++
i
)
switch
(
base64
[
i
])
{
case
'+'
:
base64
[
i
]
=
'*'
;
break
;
case
'/'
:
base64
[
i
]
=
'-'
;
break
;
case
'='
:
base64
[
i
]
=
'_'
;
break
;
default
:
break
;
}
return
base64
;
}
}
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