Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xyqb-user2
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
head_group
xyqb-user2
Commits
6e6c9d1b
Commit
6e6c9d1b
authored
Nov 02, 2017
by
技术部-任文超
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
提交jUnit,当前Demo为单次令牌切面的测试用例,已绿
parent
c39f7a6b
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
198 additions
and
46 deletions
+198
-46
Constants.java
src/main/java/cn/quantgroup/xyqb/Constants.java
+1
-1
TokenOnceValidateAdvisor.java
...uantgroup/xyqb/aspect/token/TokenOnceValidateAdvisor.java
+26
-31
TokenOnceValidator.java
...a/cn/quantgroup/xyqb/aspect/token/TokenOnceValidator.java
+1
-1
TokenOnceController.java
...p/xyqb/controller/internal/token/TokenOnceController.java
+15
-10
UserController.java
...ntgroup/xyqb/controller/internal/user/UserController.java
+2
-0
xyqb.properties
src/main/resources/config/dev/xyqb.properties
+1
-1
xyqb.properties
src/main/resources/config/test/xyqb.properties
+0
-2
TokenOnceTests.java
src/test/java/token/TokenOnceTests.java
+152
-0
No files found.
src/main/java/cn/quantgroup/xyqb/Constants.java
View file @
6e6c9d1b
...
@@ -12,7 +12,7 @@ public interface Constants {
...
@@ -12,7 +12,7 @@ public interface Constants {
String
PASSWORD_SALT
=
"_lkb"
;
String
PASSWORD_SALT
=
"_lkb"
;
String
IMAGE_CAPTCHA_KEY
=
"img_captcha:"
;
String
IMAGE_CAPTCHA_KEY
=
"img_captcha:"
;
String
TOKEN_
SINGLE_KEY_FOR_PHONE
=
"token_singl
e:for_phone:"
;
String
TOKEN_
ONCE_KEY_FOR_PHONE
=
"token_onc
e:for_phone:"
;
String
REDIS_CAPTCHA_KEY
=
"auth:"
;
String
REDIS_CAPTCHA_KEY
=
"auth:"
;
String
REDIS_CAPTCHA_KEY_PATTERN
=
REDIS_CAPTCHA_KEY
+
IMAGE_CAPTCHA_KEY
+
"*"
;
String
REDIS_CAPTCHA_KEY_PATTERN
=
REDIS_CAPTCHA_KEY
+
IMAGE_CAPTCHA_KEY
+
"*"
;
...
...
src/main/java/cn/quantgroup/xyqb/aspect/token/
SingleToken
ValidateAdvisor.java
→
src/main/java/cn/quantgroup/xyqb/aspect/token/
TokenOnce
ValidateAdvisor.java
View file @
6e6c9d1b
...
@@ -4,7 +4,6 @@ import cn.quantgroup.xyqb.Constants;
...
@@ -4,7 +4,6 @@ import cn.quantgroup.xyqb.Constants;
import
cn.quantgroup.xyqb.exception.VerificationCodeErrorException
;
import
cn.quantgroup.xyqb.exception.VerificationCodeErrorException
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
cn.quantgroup.xyqb.util.ValidationUtil
;
import
org.apache.commons.codec.binary.Base64
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.ProceedingJoinPoint
;
import
org.aspectj.lang.annotation.Around
;
import
org.aspectj.lang.annotation.Around
;
...
@@ -22,6 +21,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
...
@@ -22,6 +21,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.UnsupportedEncodingException
;
import
java.io.UnsupportedEncodingException
;
import
java.nio.charset.Charset
;
import
java.util.Base64
;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Objects
;
...
@@ -35,9 +36,9 @@ import java.util.Objects;
...
@@ -35,9 +36,9 @@ import java.util.Objects;
*/
*/
@Aspect
@Aspect
@Component
@Component
public
class
SingleToken
ValidateAdvisor
{
public
class
TokenOnce
ValidateAdvisor
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
SingleToken
ValidateAdvisor
.
class
);
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
TokenOnce
ValidateAdvisor
.
class
);
@Autowired
@Autowired
@Qualifier
(
"stringRedisTemplate"
)
@Qualifier
(
"stringRedisTemplate"
)
...
@@ -46,14 +47,14 @@ public class SingleTokenValidateAdvisor {
...
@@ -46,14 +47,14 @@ public class SingleTokenValidateAdvisor {
/**
/**
* 自动化测试忽略单次令牌校验
* 自动化测试忽略单次令牌校验
*/
*/
@Value
(
"${xyqb.auth.
singletoken.autotest.enable:fals
e}"
)
@Value
(
"${xyqb.auth.
tokenonce.autotest.enable:tru
e}"
)
private
boolean
autoTest
SingleToken
Enabled
;
private
boolean
autoTest
TokenOnce
Enabled
;
/**
/**
* 单次令牌校验切面
* 单次令牌校验切面
*/
*/
@Pointcut
(
"@annotation(cn.quantgroup.xyqb.aspect.token.
SingleToken
Validator)"
)
@Pointcut
(
"@annotation(cn.quantgroup.xyqb.aspect.token.
TokenOnce
Validator)"
)
private
void
need
SingleToken
Validate
()
{
private
void
need
TokenOnce
Validate
()
{
}
}
/**
/**
...
@@ -61,9 +62,9 @@ public class SingleTokenValidateAdvisor {
...
@@ -61,9 +62,9 @@ public class SingleTokenValidateAdvisor {
*
*
* @throws Throwable
* @throws Throwable
*/
*/
@Around
(
"need
SingleToken
Validate()"
)
@Around
(
"need
TokenOnce
Validate()"
)
private
Object
do
SingleToken
Validate
(
ProceedingJoinPoint
pjp
)
throws
Throwable
{
private
Object
do
TokenOnce
Validate
(
ProceedingJoinPoint
pjp
)
throws
Throwable
{
if
(
autoTest
SingleToken
Enabled
)
{
if
(
autoTest
TokenOnce
Enabled
)
{
return
pjp
.
proceed
();
return
pjp
.
proceed
();
}
}
boolean
checkTokenForPhone
=
checkTokenForPhone
();
boolean
checkTokenForPhone
=
checkTokenForPhone
();
...
@@ -85,27 +86,27 @@ public class SingleTokenValidateAdvisor {
...
@@ -85,27 +86,27 @@ public class SingleTokenValidateAdvisor {
}
}
// 当前用户手机号
// 当前用户手机号
String
phoneNo
=
phoneTokenMap
.
get
(
"phoneNo"
);
String
phoneNo
=
phoneTokenMap
.
get
(
"phoneNo"
);
// 当前请求的
SingleToken
// 当前请求的
TokenOnce
String
requestToken
=
phoneTokenMap
.
get
(
"requestToken"
);
String
requestToken
=
phoneTokenMap
.
get
(
"requestToken"
);
if
(
StringUtils
.
isBlank
(
phoneNo
)
||
StringUtils
.
isBlank
(
requestToken
)){
if
(
StringUtils
.
isBlank
(
phoneNo
)
||
StringUtils
.
isBlank
(
requestToken
)){
return
false
;
return
false
;
}
}
final
String
key
=
Constants
.
TOKEN_
SINGL
E_KEY_FOR_PHONE
+
phoneNo
;
final
String
key
=
Constants
.
TOKEN_
ONC
E_KEY_FOR_PHONE
+
phoneNo
;
String
singleToken
=
redisTemplate
.
opsForValue
().
get
(
key
);
String
tokenOnce
=
redisTemplate
.
opsForValue
().
get
(
key
);
//
SingleToken
不应为空值(空白、空格、null)
//
TokenOnce
不应为空值(空白、空格、null)
if
(
StringUtils
.
isBlank
(
singleToken
))
{
if
(
StringUtils
.
isBlank
(
tokenOnce
))
{
// 修正规则
// 修正规则
if
(
redisTemplate
.
hasKey
(
key
)){
if
(
redisTemplate
.
hasKey
(
key
)){
redisTemplate
.
delete
(
key
);
redisTemplate
.
delete
(
key
);
}
}
return
false
;
return
false
;
}
}
boolean
valid
=
Objects
.
equals
(
singleToken
,
requestToken
);
boolean
valid
=
Objects
.
equals
(
tokenOnce
,
requestToken
);
//
SingleToken
校验正确时删除key
//
TokenOnce
校验正确时删除key
if
(
valid
)
{
if
(
valid
)
{
redisTemplate
.
delete
(
key
);
redisTemplate
.
delete
(
key
);
}
else
{
}
else
{
LOGGER
.
info
(
"Token过期,请重新请求, token_
singl
e:for_phone:={}, requestToken={}, clientIp={}"
,
phoneNo
,
requestToken
,
request
.
getRemoteAddr
());
LOGGER
.
info
(
"Token过期,请重新请求, token_
onc
e:for_phone:={}, requestToken={}, clientIp={}"
,
phoneNo
,
requestToken
,
request
.
getRemoteAddr
());
}
}
return
valid
;
return
valid
;
}
}
...
@@ -113,25 +114,19 @@ public class SingleTokenValidateAdvisor {
...
@@ -113,25 +114,19 @@ public class SingleTokenValidateAdvisor {
/**
/**
* 单次令牌参数解析
* 单次令牌参数解析
*
*
* @param request 当前请求,其首部行必须包含形如【
SingleToken 13461067662:0123456789abcdef
】的UTF-8编码的Base64加密参数
* @param request 当前请求,其首部行必须包含形如【
TokenOnce MTM0NjEwNjc2NjI6NmFjMDY2NWItZTE5Yy00MzkyLWEyNDQtN2I2MTY5MDgzM2Y1
】的UTF-8编码的Base64加密参数
* @return 令牌参数Map 或 null
* @return 令牌参数Map 或 null
*/
*/
private
Map
<
String
,
String
>
getHeaderParam
(
HttpServletRequest
request
)
{
private
Map
<
String
,
String
>
getHeaderParam
(
HttpServletRequest
request
)
{
String
verificationHeader
=
"SingleToken
"
;
String
headerName
=
"TokenOnce
"
;
String
credential
=
request
.
getHeader
(
"authorization"
);
String
credential
=
request
.
getHeader
(
headerName
);
if
(
StringUtils
.
isBlank
(
credential
)
||
!
credential
.
startsWith
(
verificationHeader
)
)
{
if
(
StringUtils
.
isBlank
(
credential
))
{
LOGGER
.
info
(
"令牌参数无效, credential:{}"
,
credential
);
LOGGER
.
info
(
"令牌参数无效, credential:{}"
,
credential
);
return
null
;
return
null
;
}
}
credential
=
credential
.
substring
(
verificationHeader
.
length
(),
credential
.
length
());
boolean
headerParamValid
=
true
;
boolean
headerParamValid
=
true
;
byte
[]
buf
=
Base64
.
decodeBase64
(
credential
);
byte
[]
buf
=
Base64
.
getDecoder
().
decode
(
credential
.
getBytes
());
try
{
credential
=
new
String
(
buf
,
Charset
.
forName
(
"UTF-8"
));
credential
=
new
String
(
buf
,
"UTF-8"
);
}
catch
(
UnsupportedEncodingException
e
)
{
headerParamValid
=
false
;
LOGGER
.
error
(
"不支持的编码{}."
,
credential
,
e
);
}
if
(!
headerParamValid
){
if
(!
headerParamValid
){
LOGGER
.
info
(
"令牌参数无效, credential:{}"
,
credential
);
LOGGER
.
info
(
"令牌参数无效, credential:{}"
,
credential
);
return
null
;
return
null
;
...
@@ -144,7 +139,7 @@ public class SingleTokenValidateAdvisor {
...
@@ -144,7 +139,7 @@ public class SingleTokenValidateAdvisor {
}
}
// 当前用户手机号
// 当前用户手机号
String
phoneNo
=
credentialArr
[
0
];
String
phoneNo
=
credentialArr
[
0
];
// 当前请求的
SingleToken
// 当前请求的
TokenOnce
String
requestToken
=
credentialArr
[
1
];
String
requestToken
=
credentialArr
[
1
];
headerParamValid
=
headerParamValid
&&
ValidationUtil
.
validatePhoneNo
(
phoneNo
);
headerParamValid
=
headerParamValid
&&
ValidationUtil
.
validatePhoneNo
(
phoneNo
);
if
(!
headerParamValid
)
{
if
(!
headerParamValid
)
{
...
...
src/main/java/cn/quantgroup/xyqb/aspect/token/
SingleToken
Validator.java
→
src/main/java/cn/quantgroup/xyqb/aspect/token/
TokenOnce
Validator.java
View file @
6e6c9d1b
...
@@ -11,5 +11,5 @@ import java.lang.annotation.*;
...
@@ -11,5 +11,5 @@ import java.lang.annotation.*;
@Documented
@Documented
@Target
(
ElementType
.
METHOD
)
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
SingleToken
Validator
{
public
@interface
TokenOnce
Validator
{
}
}
src/main/java/cn/quantgroup/xyqb/controller/internal/token/
SingleToken
Controller.java
→
src/main/java/cn/quantgroup/xyqb/controller/internal/token/
TokenOnce
Controller.java
View file @
6e6c9d1b
...
@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.controller.internal.token;
...
@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.controller.internal.token;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
cn.quantgroup.xyqb.model.JsonResult
;
import
org.apache.commons.codec.binary.Base64
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
...
@@ -14,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.bind.annotation.RestController
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
java.nio.charset.Charset
;
import
java.util.UUID
;
import
java.util.UUID
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
...
@@ -26,9 +28,9 @@ import java.util.concurrent.TimeUnit;
...
@@ -26,9 +28,9 @@ import java.util.concurrent.TimeUnit;
*/
*/
@RestController
@RestController
@RequestMapping
(
"/token"
)
@RequestMapping
(
"/token"
)
public
class
SingleToken
Controller
implements
IBaseController
{
public
class
TokenOnce
Controller
implements
IBaseController
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
SingleToken
Controller
.
class
);
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
TokenOnce
Controller
.
class
);
private
static
final
Long
ONE_HOUR
=
1
*
60
*
60L
;
private
static
final
Long
ONE_HOUR
=
1
*
60
*
60L
;
@Autowired
@Autowired
...
@@ -36,19 +38,22 @@ public class SingleTokenController implements IBaseController {
...
@@ -36,19 +38,22 @@ public class SingleTokenController implements IBaseController {
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
private
RedisTemplate
<
String
,
String
>
redisTemplate
;
/**
/**
* 向指定用户账号(手机号)发放一枚SingleToken
* 向指定用户账号(手机号)发放一枚TokenOnce
* TokenOnce用法:其首部行必须包含形如【TokenOnce MTM0NjEwNjc2NjI6NmFjMDY2NWItZTE5Yy00MzkyLWEyNDQtN2I2MTY5MDgzM2Y1】的UTF-8编码的Base64加密参数
* 例如:Base64.getEncoder().encodeToString("13461067662:6ac0665b-e19c-4392-a244-7b61690833f5".getBytes(Charset.forName("UTF-8")));
*
* @param phoneNo 用户账号(手机号)
* @param phoneNo 用户账号(手机号)
* @return 单次令牌
* @return 单次令牌
*/
*/
@RequestMapping
(
value
=
"/
singl
e"
)
@RequestMapping
(
value
=
"/
onc
e"
)
public
JsonResult
new
SingleToken
(
HttpServletRequest
request
,
@ModelAttribute
(
"phoneNo"
)
String
phoneNo
)
{
public
JsonResult
new
TokenOnce
(
HttpServletRequest
request
,
@ModelAttribute
(
"phoneNo"
)
String
phoneNo
)
{
if
(
StringUtils
.
isBlank
(
phoneNo
)){
if
(
StringUtils
.
isBlank
(
phoneNo
)){
return
JsonResult
.
buildErrorStateResult
(
"
"
,
"fail
"
);
return
JsonResult
.
buildErrorStateResult
(
"
获取TokenOnce失败"
,
"
"
);
}
}
String
singleToken
=
UUID
.
randomUUID
().
toString
();
String
tokenOnce
=
UUID
.
randomUUID
().
toString
();
final
String
key
=
Constants
.
TOKEN_
SINGL
E_KEY_FOR_PHONE
+
phoneNo
;
final
String
key
=
Constants
.
TOKEN_
ONC
E_KEY_FOR_PHONE
+
phoneNo
;
redisTemplate
.
opsForValue
().
set
(
key
,
singleToken
,
ONE_HOUR
,
TimeUnit
.
SECONDS
);
redisTemplate
.
opsForValue
().
set
(
key
,
tokenOnce
,
ONE_HOUR
,
TimeUnit
.
SECONDS
);
return
JsonResult
.
buildSuccessResult
(
""
,
singleToken
);
return
JsonResult
.
buildSuccessResult
(
""
,
tokenOnce
);
}
}
}
}
src/main/java/cn/quantgroup/xyqb/controller/internal/user/UserController.java
View file @
6e6c9d1b
...
@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.controller.internal.user;
...
@@ -3,6 +3,7 @@ package cn.quantgroup.xyqb.controller.internal.user;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.Constants
;
import
cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator
;
import
cn.quantgroup.xyqb.aspect.captcha.CaptchaNewValidator
;
import
cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller
;
import
cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller
;
import
cn.quantgroup.xyqb.aspect.token.TokenOnceValidator
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.controller.IBaseController
;
import
cn.quantgroup.xyqb.entity.Merchant
;
import
cn.quantgroup.xyqb.entity.Merchant
;
import
cn.quantgroup.xyqb.entity.User
;
import
cn.quantgroup.xyqb.entity.User
;
...
@@ -296,6 +297,7 @@ public class UserController implements IBaseController {
...
@@ -296,6 +297,7 @@ public class UserController implements IBaseController {
* @param channelId
* @param channelId
* @return
* @return
*/
*/
@TokenOnceValidator
@RequestMapping
(
"/register"
)
@RequestMapping
(
"/register"
)
public
JsonResult
register
(
@RequestParam
String
phoneNo
,
@RequestParam
String
password
,
public
JsonResult
register
(
@RequestParam
String
phoneNo
,
@RequestParam
String
password
,
@RequestParam
String
verificationCode
,
@RequestParam
(
required
=
false
)
Long
channelId
,
@RequestParam
String
verificationCode
,
@RequestParam
(
required
=
false
)
Long
channelId
,
...
...
src/main/resources/config/dev/xyqb.properties
View file @
6e6c9d1b
...
@@ -58,7 +58,7 @@ jr58.notify.userinfo=http://xfd.test.58v5.cn/customer/quantgroup_user_info
...
@@ -58,7 +58,7 @@ jr58.notify.userinfo=http://xfd.test.58v5.cn/customer/quantgroup_user_info
# 是否启用超级验证码 "__SUPERQG__", 用于测试环境自动化测试, 线上环境可忽略此参数
# 是否启用超级验证码 "__SUPERQG__", 用于测试环境自动化测试, 线上环境可忽略此参数
xyqb.auth.captcha.super.enable
=
1
xyqb.auth.captcha.super.enable
=
1
# 单次令牌验证, 用于测试环境自动化测试, 线上环境可忽略此参数
# 单次令牌验证, 用于测试环境自动化测试, 线上环境可忽略此参数
xyqb.auth.
singletoken.autotest.enable
=
tru
e
xyqb.auth.
tokenonce.autotest.enable
=
fals
e
#首参数校验
#首参数校验
xyqb.fplock.limit.byhour
=
3
xyqb.fplock.limit.byhour
=
3
...
...
src/main/resources/config/test/xyqb.properties
View file @
6e6c9d1b
...
@@ -39,8 +39,6 @@ jr58.notify.userinfo=http://xfd.test.58v5.cn/customer/quantgroup_user_info
...
@@ -39,8 +39,6 @@ jr58.notify.userinfo=http://xfd.test.58v5.cn/customer/quantgroup_user_info
# 图形验证码
# 图形验证码
# 是否启用超级验证码 "__SUPERQG__", 用于测试环境自动化测试, 线上环境可忽略此参数
# 是否启用超级验证码 "__SUPERQG__", 用于测试环境自动化测试, 线上环境可忽略此参数
xyqb.auth.captcha.super.enable
=
1
xyqb.auth.captcha.super.enable
=
1
# 单次令牌验证, 用于测试环境自动化测试, 线上环境可忽略此参数
xyqb.auth.singletoken.autotest.enable
=
true
#首参数校验
#首参数校验
xyqb.fplock.limit.byhour
=
3
xyqb.fplock.limit.byhour
=
3
xyqb.fplock.limit.byday
=
5
xyqb.fplock.limit.byday
=
5
...
...
src/test/java/token/TokenOnceTests.java
0 → 100644
View file @
6e6c9d1b
package
token
;
import
cn.quantgroup.xyqb.Bootstrap
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
org.junit.Assert
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.http.MediaType
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.test.web.servlet.MockMvc
;
import
org.springframework.test.web.servlet.MvcResult
;
import
org.springframework.test.web.servlet.request.MockMvcRequestBuilders
;
import
org.springframework.test.web.servlet.setup.MockMvcBuilders
;
import
org.springframework.web.context.WebApplicationContext
;
import
java.nio.charset.Charset
;
import
java.util.Base64
;
import
static
org
.
springframework
.
test
.
web
.
servlet
.
result
.
MockMvcResultMatchers
.
status
;
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringApplicationConfiguration
(
classes
=
Bootstrap
.
class
)
@WebAppConfiguration
public
class
TokenOnceTests
{
final
String
phoneNo
=
"13461067662"
;
private
MockMvc
mvc
;
@Autowired
WebApplicationContext
webApplicationConnect
;
@Before
public
void
setUp
()
throws
JsonProcessingException
{
mvc
=
MockMvcBuilders
.
webAppContextSetup
(
webApplicationConnect
).
build
();
}
/**
* 测试Server是否可达
* @throws Exception
*/
@Test
public
void
testServer
()
throws
Exception
{
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
"/"
).
accept
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isOk
());
}
/**
* 测试TokenOnce发放服务
* @throws Exception
*/
@Test
public
void
testTokenOnce
()
throws
Exception
{
String
tokenOnceUri
=
"/token/once"
;
MvcResult
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
tokenOnceUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
header
(
"Session-Id"
,
"82107d0326772b8b5c72ec11801b8ab3"
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
String
content
=
mvcResult
.
getResponse
().
getContentAsString
();
JSONObject
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
Object
code
=
jsonResult
.
get
(
"code"
);
Assert
.
assertEquals
(
"0000"
,
code
);
Object
data
=
jsonResult
.
get
(
"data"
);
Assert
.
assertEquals
(
data
,
""
);
Object
msg
=
jsonResult
.
get
(
"msg"
);
Assert
.
assertEquals
(
"获取TokenOnce失败"
,
jsonResult
.
get
(
"msg"
));
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
tokenOnceUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
param
(
"phoneNo"
,
phoneNo
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
content
=
mvcResult
.
getResponse
().
getContentAsString
();
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
code
=
jsonResult
.
get
(
"code"
);
Assert
.
assertEquals
(
"0000"
,
code
);
data
=
jsonResult
.
get
(
"data"
);
Assert
.
assertNotNull
(
data
);
msg
=
jsonResult
.
get
(
"msg"
);
Assert
.
assertEquals
(
msg
,
""
);
}
/**
* 测试TokenOnce切面
* @throws Exception
*/
@Test
public
void
testAspect
()
throws
Exception
{
// 获取TokenOnce
String
tokenOnceUri
=
"/token/once"
;
MvcResult
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
tokenOnceUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
param
(
"phoneNo"
,
phoneNo
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
String
content
=
mvcResult
.
getResponse
().
getContentAsString
();
JSONObject
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
Object
code
=
jsonResult
.
get
(
"code"
);
Assert
.
assertEquals
(
"0000"
,
code
);
Object
data
=
jsonResult
.
get
(
"data"
);
Assert
.
assertNotNull
(
data
);
StringBuilder
tokenBuilder
=
new
StringBuilder
(
phoneNo
);
String
tokenOnce
=
new
String
(
Base64
.
getEncoder
().
encodeToString
(
tokenBuilder
.
append
(
":"
).
append
(
data
).
toString
().
getBytes
(
Charset
.
forName
(
"UTF-8"
))));
// 第一次使用TokenOnce
String
aspectUri
=
"/user/register"
;
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
aspectUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
header
(
"TokenOnce"
,
tokenOnce
)
.
param
(
"phoneNo"
,
phoneNo
)
.
param
(
"password"
,
"Qg123456"
)
.
param
(
"verificationCode"
,
"1234"
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
content
=
mvcResult
.
getResponse
().
getContentAsString
();
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
code
=
jsonResult
.
get
(
"code"
);
Object
businessCode
=
jsonResult
.
get
(
"businessCode"
);
Assert
.
assertEquals
(
"0000"
,
code
);
Assert
.
assertNotEquals
(
"0002"
,
businessCode
);
// 使用过期的TokenOnce
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
aspectUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
header
(
"TokenOnce"
,
tokenOnce
)
.
param
(
"phoneNo"
,
phoneNo
)
.
param
(
"password"
,
"Qg123456"
)
.
param
(
"verificationCode"
,
"1234"
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
content
=
mvcResult
.
getResponse
().
getContentAsString
();
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
code
=
jsonResult
.
get
(
"code"
);
Assert
.
assertEquals
(
"0000"
,
code
);
businessCode
=
jsonResult
.
get
(
"businessCode"
);
Assert
.
assertEquals
(
"0002"
,
businessCode
);
// 不使用TokenOnce
mvcResult
=
mvc
.
perform
(
MockMvcRequestBuilders
.
get
(
aspectUri
).
accept
(
MediaType
.
APPLICATION_JSON
)
.
param
(
"phoneNo"
,
phoneNo
)
.
param
(
"password"
,
"Qg123456"
)
.
param
(
"verificationCode"
,
"1234"
))
.
andExpect
(
status
().
isOk
())
.
andReturn
();
content
=
mvcResult
.
getResponse
().
getContentAsString
();
jsonResult
=
JSON
.
parseObject
(
new
String
(
content
));
code
=
jsonResult
.
get
(
"code"
);
Assert
.
assertEquals
(
"0000"
,
code
);
businessCode
=
jsonResult
.
get
(
"businessCode"
);
Assert
.
assertEquals
(
"0002"
,
businessCode
);
}
}
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