Commit d3c4e1e9 authored by 技术部-任文超's avatar 技术部-任文超

Merge branch 'master' into 20180424-modify-UserDetail

parents 5b69b871 87deaeb0
......@@ -29,6 +29,23 @@
</properties>
<dependencies>
<!-- swagger2 start -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>RELEASE</version>
</dependency>
<!-- swagger2 end -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
......
package cn.quantgroup.xyqb.config.swagger;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.google.common.base.Predicates;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger文档框架
*/
@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Value("${openapi.swagger.on:false}")
private Boolean swaggerOn;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false)
.enable(swaggerOn)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("xyqb-user api")
.description("用户中心接口文档")
.contact(new Contact("wenchao.ren", "", "wenchao.ren@quantgroup.cn"))
.license("Apache License Version 2.0")
.licenseUrl("https://github.com/springfox/springfox/blob/master/LICENSE")
.version("2.0")
.build();
}
@Component
@Primary
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
setSerializationInclusion(JsonInclude.Include.NON_NULL);
configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
enable(SerializationFeature.INDENT_OUTPUT);
}
}
}
......@@ -393,7 +393,7 @@ public class InnerController implements IBaseController {
*/
@LogHttpCaller
@RequestMapping("/user_detail/update")
public JsonResult updateUserQQ(String qq, String email, Long userId) {
public JsonResult updateUserDetail(String qq, String email, Long userId) {
if (Objects.isNull(userId) || userId == 0L) {
return JsonResult.buildErrorStateResult("userId为空", null);
}
......
package cn.quantgroup.xyqb.controller.external.user;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.aspect.accessable.IpValidator;
import cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.service.api.IUserApiService;
import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.service.user.IUserService;
import cn.quantgroup.xyqb.session.XyqbSessionContextHolder;
import cn.quantgroup.xyqb.util.ValidationUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Objects;
/**
* Created by FrankChow on 15/12/16.
*/
@Slf4j
@RestController
@RequestMapping("/api")
public class UserApiController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserApiController.class);
@Autowired
private IUserApiService userApiService;
@Autowired
@Resource
private IUserService userService;
@Resource
private IUserApiService userApiService;
@Resource
private ISessionService sessionService;
@Resource
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> stringRedisTemplate;
@RequestMapping("/user/check")
public JsonResult userImportCheck(String phoneNo, String registerFrom) {
if ("244".equals(registerFrom)) {
LOGGER.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", false);
}
if (StringUtils.isEmpty(phoneNo) || StringUtils.isEmpty(registerFrom)) {
LOGGER.error("[user_import_check]检查传入的参数,参数不全。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
log.error("[user_import_check]检查传入的参数,参数不全。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("检查传入的参数,参数不全。", null);
}
boolean checkPassed = userApiService.userImportCheck(phoneNo);
if (checkPassed) {
LOGGER.info("[user_import_check]用户可以导入。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
log.info("[user_import_check]用户可以导入。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildSuccessResult("用户可以导入", checkPassed);
}
LOGGER.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
log.info("[user_import_check]用户导入检查拒绝。phoneNo=[{}], registerFrom=[{}]", phoneNo, registerFrom);
return JsonResult.buildErrorStateResult("用户导入检查拒绝", checkPassed);
}
......@@ -59,4 +74,44 @@ public class UserApiController {
return JsonResult.buildErrorStateResult(null, null, 2L);
}
/**
* 检查token是否有效
* 如果有效,可选择是否延续生命期(延续后有效期24Hour)
*
* @param token - sid,session的id
* @param prolong - 是否延续生命期,可选参数,默认为: false - 不延续
* @return
*/
@ApiOperation(notes = "检查token是否有效,如果有效,可选择是否延续生命期(延续后有效期24Hour)", value = "Check token and then prolong session", nickname = "checkToken")
@LogHttpCaller
@IpValidator
@RequestMapping(value = "/valid/{token}", method = RequestMethod.POST)
public JsonResult checkToken(@ApiParam(value = "sid,session的id", required = true) @PathVariable("token") String token,
@ApiParam(value = "是否延续生命期,可选参数,默认为: false - 不延续", required = false) @RequestParam(name = "prolong", required = false, defaultValue = "false") Boolean prolong) {
if(Objects.isNull(token) || !ValidationUtil.validateToken(token)){
return JsonResult.buildErrorStateResult("token invalid", token);
}
String tokenKey = Constants.SESSION_PREFIX + token;
String tokenKey2 = Constants.Session.USER_SESSION_CACHE + token;
// 判断token是否存在
boolean exist = stringRedisTemplate.hasKey(tokenKey)||stringRedisTemplate.hasKey(tokenKey2);
/* token存在且需要延续时,进一步判断session是否有效,有效时,自动续期 */
if(Boolean.logicalAnd(exist, prolong)){
// 获取session信息
SessionStruct sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis(token);
if(Objects.isNull(sessionStruct)) {
/* 如果没有获取到session信息则返回错误信息 */
return JsonResult.buildErrorStateResult("session invalid", token);
}else{
/* 延续session生命期 */
try {
sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
} finally {
XyqbSessionContextHolder.releaseSession();
}
}
}
return JsonResult.buildSuccessResult("token valid", token);
}
}
package cn.quantgroup.xyqb.controller.internal.login;
import cn.quantgroup.xyqb.aspect.logcaller.LogHttpCaller;
import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserRet;
......@@ -15,6 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* 查询已登录信息
* Created by Miraculous on 2016/12/30.
......@@ -25,8 +28,9 @@ import org.springframework.web.bind.annotation.RestController;
public class AuthInfoController implements IBaseController {
@LogHttpCaller
@RequestMapping("/info/login")
public JsonResult loginInfo() {
public JsonResult loginInfo(HttpServletRequest request) {
SessionStruct sessionStruct = getCurrentSessionFromRedis();
if(null != sessionStruct) {
log.info("从用户中心获取到了用户登录信息:phone:[{}]", sessionStruct.getValues().getUser().getPhoneNo());
......@@ -40,10 +44,10 @@ public class AuthInfoController implements IBaseController {
context.setBtMerchantId(sessionStruct.getValues().getLoginProperties().getBtMerchantId());
//有ThreadLocal不释放的问题,不可再使用原来方式了
loginInfo.setLoginContext(context);
log.info("[/auth/info/login] SessionStruct数据:{}", JSONObject.toJSONString(sessionStruct));
log.info("[/auth/info/login] LoginInfo数据:{}", JSONObject.toJSONString(loginInfo));
log.info("[/auth/info/login] SessionStruct数据:{}, LoginInfo数据:{}", JSONObject.toJSONString(sessionStruct), JSONObject.toJSONString(loginInfo));
return JsonResult.buildSuccessResult("", loginInfo);
}
log.info("[/auth/info/login] 未查到用户登录信息, request-Header:{}", JSON.toJSONString(getRequestHeaderMap(request)));
return JsonResult.buildErrorStateResult("用户未登录",null);
}
......
......@@ -28,9 +28,6 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/platform/api")
public class PlatformAPIController implements IBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(PlatformAPIController.class);
@Autowired
private IPageService pageService;
@Autowired
......@@ -81,6 +78,4 @@ public class PlatformAPIController implements IBaseController {
return JsonResult.buildSuccessResult("", ImmutableMap.of("type", "user", "transition", nextPage));
}
}
......@@ -9,10 +9,8 @@ import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.entity.Merchant;
import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserDetail;
import cn.quantgroup.xyqb.entity.WechatUserInfo;
import cn.quantgroup.xyqb.exception.UserNotExistException;
import cn.quantgroup.xyqb.exception.VerificationCodeErrorException;
import cn.quantgroup.xyqb.exception.WechatRelateUserException;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserModel;
import cn.quantgroup.xyqb.model.UserStatistics;
......@@ -29,11 +27,9 @@ import cn.quantgroup.xyqb.util.MqUtils;
import cn.quantgroup.xyqb.util.PasswordUtil;
import cn.quantgroup.xyqb.util.ValidationUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
......@@ -50,12 +46,11 @@ import java.util.*;
* Http服务接口:用户注册、登录、重置密码
* Created by FrankChow on 15/7/5.
*/
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController implements IBaseController {
private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class);
@Autowired
private IUserService userService;
......@@ -84,7 +79,7 @@ public class UserController implements IBaseController {
@RequestMapping("/test")
public JsonResult test() {
HttpServletRequest request = getRequest();
IPUtil.logIp(LOGGER, request);
IPUtil.logIp(log, request);
return JsonResult.buildSuccessResult("", getCurrentUserFromRedis());
}
......@@ -111,7 +106,7 @@ public class UserController implements IBaseController {
@RequestParam(required = false,defaultValue = "xyqb") String key,
@RequestParam(required = false) String dimension,
HttpServletRequest request) {
LOGGER.info("loginV1 -> channelId:{},appChennel:{},createdFrom:{},userId:{},key:{},dimension:{}",channelId, appChannel, createdFrom, userId, key, dimension);
log.info("loginV1 -> channelId:{},appChennel:{},createdFrom:{},userId:{},key:{},dimension:{}",channelId, appChannel, createdFrom, userId, key, dimension);
return login(channelId, appChannel, createdFrom, userId, key, dimension, request);
}
......@@ -125,7 +120,7 @@ public class UserController implements IBaseController {
@RequestParam(required = false,defaultValue = "xyqb") String key,
@RequestParam(required = false) String dimension,
HttpServletRequest request) {
LOGGER.info("login -> channelId:{},appChannel:{},createdFrom:{},userId:{},key:{},dimension:{}",channelId,appChannel,createdFrom,userId,key,dimension);
log.info("login -> channelId:{},appChannel:{},createdFrom:{},userId:{},key:{},dimension:{}",channelId,appChannel,createdFrom,userId,key,dimension);
Merchant merchant = merchantService.findMerchantByName(key);
if (merchant == null) {
return JsonResult.buildErrorStateResult("未知的连接", null);
......@@ -160,7 +155,7 @@ public class UserController implements IBaseController {
@RequestParam(required = false) String dimension,
@RequestParam(name = "click_id", required = false) String clickId,
HttpServletRequest request) {
LOGGER.info("login/fastV1 -> channelId:{},appChennel:{},createdFrom:{},key:{},btRegisterChannelId:{},dimension:{},clickId:{}",channelId, appChannel, createdFrom, key, btRegisterChannelId, dimension, clickId);
log.info("login/fastV1 -> channelId:{},appChennel:{},createdFrom:{},key:{},btRegisterChannelId:{},dimension:{},clickId:{}",channelId, appChannel, createdFrom, key, btRegisterChannelId, dimension, clickId);
return loginFast(channelId, appChannel, createdFrom, key, btRegisterChannelId, dimension, clickId, request);
}
......@@ -174,7 +169,7 @@ public class UserController implements IBaseController {
@RequestParam(name = "click_id", required = false) String clickId,
HttpServletRequest request) {
Map<String, JsonResult> validMap = getHeaderParam(request);
LOGGER.info("login/fast -> channelId:{},appChannel:{},createdFrom:{},btRegisterChannelId:{},key:{},dimension:{},clickId:{}",channelId,appChannel,createdFrom,btRegisterChannelId,key,dimension, clickId);
log.info("login/fast -> channelId:{},appChannel:{},createdFrom:{},btRegisterChannelId:{},key:{},dimension:{},clickId:{}",channelId,appChannel,createdFrom,btRegisterChannelId,key,dimension, clickId);
if (null != validMap.get("fail")) {
return validMap.get("fail");
}
......@@ -185,7 +180,7 @@ public class UserController implements IBaseController {
JsonResult successResult = validMap.get("success");
String phoneNo = successResult.getData().toString();
if (!ValidationUtil.validatePhoneNo(phoneNo)) {
LOGGER.info("用户快速登录失败,手机号错误, createdFrom:{},phoneNo:{}", createdFrom, phoneNo);
log.info("用户快速登录失败,手机号错误, createdFrom:{},phoneNo:{}", createdFrom, phoneNo);
throw new UserNotExistException("手机号错误");
}
String verificationCode = successResult.getMsg();
......@@ -193,7 +188,7 @@ public class UserController implements IBaseController {
verifyPhoneAndCode(phoneNo, verificationCode);
User user = userService.findByPhoneWithCache(phoneNo);
if (user != null && !user.getEnable()) {
LOGGER.error("用户不存在,或者已经注销,phoneNo:{}",phoneNo);
log.error("用户不存在,或者已经注销,phoneNo:{}",phoneNo);
return JsonResult.buildErrorStateResult("登录失败", null);
}
if (user == null) {
......@@ -242,7 +237,7 @@ public class UserController implements IBaseController {
}
String phoneNo = credentialArr[0];
String verificationCode = credentialArr[1];
LOGGER.info("用户快速登录,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
log.info("用户快速登录,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
if (!ValidationUtil.validatePhoneNo(phoneNo) || StringUtils.isBlank(verificationCode)) {
result.put("fail", JsonResult.buildErrorStateResult("登录失败", null));
return result;
......@@ -265,17 +260,17 @@ public class UserController implements IBaseController {
@RequestParam String verificationCode, @RequestParam(required = false) Long channelId,
@RequestParam(required = false) Long registerFrom,
@RequestParam(required = false)Long btRegisterChannelId,@RequestParam(required = false)String dimension) {
LOGGER.info("用户注册:register -> phoneNo:{}, verificationCode:{}, channelId:{}, registerFrom:{},btRegisterChannelId:{},dimension:{}", phoneNo, verificationCode, channelId, registerFrom,btRegisterChannelId,dimension);
log.info("用户注册:register -> phoneNo:{}, verificationCode:{}, channelId:{}, registerFrom:{},btRegisterChannelId:{},dimension:{}", phoneNo, verificationCode, channelId, registerFrom,btRegisterChannelId,dimension);
if (!ValidationUtil.validatePhoneNo(phoneNo)) {
LOGGER.info("用户注册失败,手机号错误:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
log.info("用户注册失败,手机号错误:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return JsonResult.buildErrorStateResult("手机号错误", null);
}
if (StringUtils.isEmpty(password)) {
LOGGER.info("用户注册失败,密码不能为空:register -> registerFrom:{}, phoneNo:{}, password:{}", registerFrom, phoneNo, password);
log.info("用户注册失败,密码不能为空:register -> registerFrom:{}, phoneNo:{}, password:{}", registerFrom, phoneNo, password);
return JsonResult.buildErrorStateResult("密码不能为空", null);
}
if (password.length() < 6 || password.length() > 12) {
LOGGER.info("用户注册失败,密码长度须在6位至12位之间:register -> registerFrom:{}, phoneNo:{}, password:{}", registerFrom, phoneNo, password);
log.info("用户注册失败,密码长度须在6位至12位之间:register -> registerFrom:{}, phoneNo:{}, password:{}", registerFrom, phoneNo, password);
return JsonResult.buildErrorStateResult("密码应为6-12位", null);
}
if (null == registerFrom) {
......@@ -283,14 +278,14 @@ public class UserController implements IBaseController {
}
verifyPhoneAndCode(phoneNo, verificationCode);
if (userService.exist(phoneNo)) {
LOGGER.info("用户注册失败,该手机号已经被注册:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
log.info("用户注册失败,该手机号已经被注册:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return JsonResult.buildErrorStateResult("该手机号已经被注册", null);
}
if (!userRegisterService.register(phoneNo, password, registerFrom, getIp(), channelId,btRegisterChannelId,dimension)) {
LOGGER.info("用户快速注册失败,请稍后重试, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
log.info("用户快速注册失败,请稍后重试, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return JsonResult.buildErrorStateResult("注册失败,请稍后重试", null);
}
LOGGER.info("用户注册成功:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
log.info("用户注册成功:register -> registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return JsonResult.buildSuccessResult(null, null);
}
......@@ -302,9 +297,9 @@ public class UserController implements IBaseController {
*/
@RequestMapping("/exist")
public JsonResult exist(@RequestParam String phoneNo) {
LOGGER.info("检查用户是否存在, phoneNo:{}", phoneNo);
log.info("检查用户是否存在, phoneNo:{}", phoneNo);
if (userService.exist(phoneNo)) {
LOGGER.info("该手机号已经注册, phoneNo:{}", phoneNo);
log.info("该手机号已经注册, phoneNo:{}", phoneNo);
return JsonResult.buildErrorStateResult("该手机号已经注册", null);
}
return JsonResult.buildSuccessResult(null, null);
......@@ -318,7 +313,7 @@ public class UserController implements IBaseController {
*/
@RequestMapping("/exist_check")
public JsonResult existForResetPwd(@RequestParam String phoneNo) {
LOGGER.info("检查用户是否存在, phoneNo:{}", phoneNo);
log.info("检查用户是否存在, phoneNo:{}", phoneNo);
return JsonResult.buildSuccessResult(null, userService.exist(phoneNo));
}
......@@ -347,7 +342,7 @@ public class UserController implements IBaseController {
}
verifyPhoneAndCode(phoneNo, verificationCode);
if (!userService.exist(phoneNo)) {
LOGGER.info("修改密码失败,该手机号尚未注册, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
log.info("修改密码失败,该手机号尚未注册, registerFrom:{}, phoneNo:{}", registerFrom, phoneNo);
return JsonResult.buildErrorStateResult("该手机号尚未注册", null);
}
if (!userService.resetPassword(phoneNo, password)) {
......@@ -355,16 +350,19 @@ public class UserController implements IBaseController {
}
// TODO 加渠道号
LOGGER.info("修改密码成功, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom);
log.info("修改密码成功, phoneNo:{}, registerFrom:{}", phoneNo, registerFrom);
return JsonResult.buildSuccessResult(null, null);
}
/**
* 检查token是否已经过期不存在了
*
* @param token
* @param token - sid,session的id
* @return
*/
@LogHttpCaller
@RequestMapping("/exists_token")
public JsonResult checkToken(@RequestParam String token) {
if(StringUtils.isEmpty(token)){
......@@ -373,14 +371,16 @@ public class UserController implements IBaseController {
if(token.contains("*")){
return JsonResult.buildSuccessResult(null,false);
}
String tokenKey = Constants.SESSION_PREFIX + token;
String tokenKey2 = Constants.Session.USER_SESSION_CACHE + token;
return JsonResult.buildSuccessResult(null, stringRedisTemplate.hasKey(tokenKey)||stringRedisTemplate.hasKey(tokenKey2));
// 判断token是否存在
boolean exist = stringRedisTemplate.hasKey(tokenKey)||stringRedisTemplate.hasKey(tokenKey2);
return JsonResult.buildSuccessResult("token valid", exist);
}
@RequestMapping("/syncUserInfo")
public JsonResult syncUserInfo() {
public JsonResult syncUserInfo(HttpServletRequest request) {
log.error("[监控][UserController][syncUserInfo] request-Header:{}", JSON.toJSONString(getRequestHeaderMap(request)));
User user = getCurrentUserFromRedis();
if (null == user) {
return JsonResult.buildErrorStateResult(null, null);
......@@ -400,7 +400,7 @@ public class UserController implements IBaseController {
//增加登陆统计发送
UserStatistics statistics=new UserStatistics(user,dimension,1,channelId);
MqUtils.sendLoanVest(statistics);
LOGGER.info("用户登陆成功phonNo:{},当前ip:{},用户登陆信息:{}",user.getPhoneNo(), IPUtil.getRemoteIP(request), statistics);
log.info("用户登陆成功phonNo:{},当前ip:{},用户登陆信息:{}",user.getPhoneNo(), IPUtil.getRemoteIP(request), statistics);
return new JsonResult(sessionService.createSession(channelId, createdFrom, appChannel, user, merchant));
}
......@@ -415,12 +415,12 @@ public class UserController implements IBaseController {
try {
bufStr = new String(buf, "UTF-8");
} catch (UnsupportedEncodingException e) {
LOGGER.error("不支持的编码: ", e);
log.error("不支持的编码: ", e);
}
String clientIp = getIp();
String[] credentialArr = bufStr.split(":");
if (credentialArr.length != 2) {
LOGGER.info("用户登录失败:{}", bufStr);
log.info("用户登录失败:{}", bufStr);
// 向该ipv4添加错误计数器
lockIpv4Service.countErrorByIpv4(clientIp);
return null;
......@@ -456,7 +456,7 @@ public class UserController implements IBaseController {
//查询用户
User user = userService.findByUuidInDb(userId);
if (Objects.isNull(user) || !user.getEnable()) {
LOGGER.error("用户不存在,或者已经注销,userId:{}",userId);
log.error("用户不存在,或者已经注销,userId:{}",userId);
return JsonResult.buildErrorStateResult("登录失败", null);
} else if(!wechatRelateUserIfNecessary(user, request)){
return JsonResult.buildErrorStateResult("登录时微信关联失败", null);
......@@ -482,7 +482,7 @@ public class UserController implements IBaseController {
if(!ready){
return true;
}else if(Objects.isNull(user) || Objects.isNull(user.getId()) || StringUtils.isBlank(request.getParameter(Constants.WECHAT_OPEN_ID))){
LOGGER.warn("微信关联失败,user:{}, request-Header:{}",user, JSON.toJSONString(getRequestHeaderMap(request)));
log.warn("微信关联失败,user:{}, request-Header:{}",user, JSON.toJSONString(getRequestHeaderMap(request)));
return false;
}
Long userId = user.getId();
......@@ -491,75 +491,11 @@ public class UserController implements IBaseController {
int rows = wechatService.relateUser(userId, phoneNo, request.getParameter(Constants.WECHAT_OPEN_ID));
return rows > 0;
}catch (Exception e){
LOGGER.error("微信关联失败,user:{}, request-Header:{}",user, JSON.toJSONString(getRequestHeaderMap(request)), e);
log.error("微信关联失败,user:{}, request-Header:{}",user, JSON.toJSONString(getRequestHeaderMap(request)), e);
}
return false;
}
/**
* 绑定微信
* @param openId - 微信openId
* @return
*/
@LogHttpCaller
@RequestMapping("/associate_wechat")
public JsonResult associateWithWechat(String openId, HttpServletRequest request) {
User user = getCurrentUserFromRedis();
LOGGER.error("[UserController][associateWithWechat][非法请求]微信关联,user:{},openId:{},request-Header:{}",user, openId, JSON.toJSONString(getRequestHeaderMap(request)));
return JsonResult.buildSuccessResult("[非法请求]微信关联", null, 1L);
/*if(Objects.isNull(user) || Objects.isNull(user.getId())){
LOGGER.warn("微信关联失败,用户未登录:user:[{}],openId:[{}]",user,openId);
return JsonResult.buildErrorStateResult("请登陆后重新操作", null);
}
Long userId = user.getId();
*//* 判断用户是否已绑定其他微信 *//*
WechatUserInfo userInfoInDb = wechatService.queryByUserId(userId);
if (Objects.nonNull(userInfoInDb)) {
if(Objects.equals(openId, userInfoInDb.getOpenId())){
LOGGER.info("微信关联成功:重复关联:跳过:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfoInDb);
return JsonResult.buildSuccessResult("微信关联成功", null);
}else if(StringUtils.isNotBlank(userInfoInDb.getOpenId())){
// 不做绑定
LOGGER.warn("微信关联失败,该用户已绑定其他微信:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfoInDb);
return JsonResult.buildErrorStateResult("该用户已绑定其他微信", null);
}else{
// 清除无效微信信息
wechatService.forbiddenUserWeChat(userId);
}
}
*//* 执行绑定 *//*
WechatUserInfo userInfo = wechatService.findWechatUserInfoFromDb(openId);
LOGGER.info("微信关联:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo);
// 无微信信息
if (userInfo == null) {
LOGGER.warn("微信关联失败,缺少微信信息:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo);
return JsonResult.buildErrorStateResult("还没有保存微信信息", null);
}
// 排他性 - 先入为主
if (Objects.nonNull(userInfo.getUserId()) && userInfo.getUserId()>0 && !Objects.equals(userId, userInfo.getUserId())) {
LOGGER.warn("微信关联失败,该微信已经被其他用户绑定:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo);
return JsonResult.buildErrorStateResult("该微信已经被其他用户绑定", null);
}
*//*
* 未绑定信用钱包用户
*//*
try {
int rows = wechatService.relateUser(userId, user.getPhoneNo(), openId);
if(rows > 0){
LOGGER.info("微信关联成功:rows:{}, user:[{}],openId:[{}],wechatUserInfo:[{}]",rows,user,openId,userInfo);
return JsonResult.buildSuccessResult("微信关联成功", null);
}else {
LOGGER.warn("微信关联失败,保存遇到问题:rows:{}, user:[{}],openId:[{}],wechatUserInfo:[{}]",rows,user,openId,userInfo);
return JsonResult.buildErrorStateResult("微信关联失败", null);
}
} catch (Exception ex) {
// 不做绑定
LOGGER.warn("微信关联失败,保存遇到问题:user:[{}],openId:[{}],wechatUserInfo:[{}]",user,openId,userInfo, ex);
return JsonResult.buildErrorStateResult("微信关联失败", null);
}*/
}
/**
* 校验短信验证码
* @param phoneNo
......@@ -575,7 +511,7 @@ public class UserController implements IBaseController {
if(smsService.needResendCode(phoneNo)){
throw new VerificationCodeErrorException("验证码失效,请重新获取");
}
LOGGER.info("验证码校验失败,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
log.info("验证码校验失败,phoneNo:{} , verificationCode:{}", phoneNo, verificationCode);
throw new VerificationCodeErrorException("短信验证码错误");
}
}
......
......@@ -17,6 +17,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;
/**
* Created by 11 on 2016/12/29.
......@@ -24,10 +25,13 @@ import java.io.PrintWriter;
@Component
public class RequestFilter implements Filter {
private static final String[] ALLOWED_PATTERNS = {
"/wechat/**", "/config/**", "/api/**", "/query/**", "/user_detail/**", "/hello/**", "/innerapi/**", "/app/**", "/motan/**", "/user/**", "/lock/**",
"/auth/info/login", "/platform/api/page/return_url", "/MP_verify_AWiagUn4kZiwmTt0.txt", "/tech/health/check"
};
/**
* 带状态
*/
private static final String[] ALLOWED_PATTERNS = {"/auth/info/login", "/platform/api/page/next"};
/**
* 带状态请求鉴权失败时的响应信息
*/
private static final String UNAUTH_RESULT = JSONObject.toJSONString(JsonResult.buildErrorStateResult("登录失败", null));
@Autowired
private ISessionService sessionService;
......@@ -41,38 +45,37 @@ public class RequestFilter implements Filter {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestPath = getRequestPath(request);
SessionStruct sessionStruct;
if (!isMatch(requestPath)) {
//获取session信息,如果没有获取到session信息则返回错误信息
sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis();
if (sessionStruct == null) {
// 带状态接口
if(isMatch(request)){
// 需获取session信息
SessionStruct sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis();
if(Objects.isNull(sessionStruct)) {
/* 如果没有获取到session信息则返回错误信息 */
response.setStatus(401);
response.setHeader("Content-Type", "application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.print(UNAUTH_RESULT);
writer.close();
return;
}
try {
filterChain.doFilter(request, response);
} finally {
sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis();
if (sessionStruct != null) {
try {
sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
} finally {
XyqbSessionContextHolder.releaseSession();
}
}else{
/* 延续session生命期 */
try {
sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
} finally {
XyqbSessionContextHolder.releaseSession();
}
}
} else {
filterChain.doFilter(request, response);
}
filterChain.doFilter(request, response);
}
private boolean isMatch(String path) {
/**
* 判断是否带状态请求
* @param request
* @return
*/
private boolean isMatch(HttpServletRequest request) {
String path = getRequestPath(request);
for (String pattern : ALLOWED_PATTERNS) {
if (matcher.match(pattern, path)) {
return true;
......@@ -83,8 +86,7 @@ public class RequestFilter implements Filter {
private String getRequestPath(HttpServletRequest request) {
String url = request.getServletPath();
if (request.getPathInfo() != null) {
if (Objects.nonNull(request.getPathInfo())) {
url += request.getPathInfo();
}
return url;
......
......@@ -152,7 +152,7 @@ public class SessionServiceImpl implements ISessionService {
Constants.Session.ONE_DAY, TimeUnit.SECONDS);
String key = generateLoginPropertiesKey(sessionValue.getUser().getId(), sessionValue.getLoginProperties());
stringRedisTemplate.opsForValue().set(key, token, Constants.Session.ONE_DAY, TimeUnit.SECONDS);
log.info("[Session生命期延续],token:{},有效期:[24Hour]", token);
setUserIdTokenKeys(sessionValue.getUser().getId(), key);
}
......@@ -181,18 +181,21 @@ public class SessionServiceImpl implements ISessionService {
public SessionStruct findSessionBySessionId(String sessionId) {
String sessionValue = findSessionValueBySessionId(sessionId);
if (StringUtils.isEmpty(sessionValue)) {
log.warn("[SessionServiceImpl][findSessionBySessionId] session data 未找到:sid:{}", sessionId);
return null;
}
try {
SessionValue value = JSON.parseObject(sessionValue, SessionValue.class);
if (null == value) {
log.warn("[SessionServiceImpl][findSessionBySessionId] session data 未找到:sid:{},sessionValue:{}", sessionId, sessionValue);
return null;
}
SessionStruct struct = new SessionStruct();
struct.setSid(sessionId);
struct.setValues(value);
return struct;
} catch (Exception ex) {
} catch (Exception e) {
log.warn("[SessionServiceImpl][findSessionBySessionId] 序列化SessionValue出错:sid:{},sessionValue:{}", sessionId, sessionValue, e);
return null;
}
......
......@@ -4,6 +4,7 @@ import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.model.session.SessionValue;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -17,10 +18,10 @@ import java.util.Objects;
/**
* Created by Miraculous on 2016/12/29.
*/
@Slf4j
public class XyqbSessionContextHolder {
private static final ThreadLocal<SessionStruct> threadSession = new ThreadLocal<>();
private static final Logger LOGGER = LoggerFactory.getLogger(XyqbSessionContextHolder.class);
public static RedisTemplate<String, String> redisTemplate = null;
public static SessionStruct getXSession() {
......@@ -46,20 +47,21 @@ public class XyqbSessionContextHolder {
}
String result = redisTemplate.opsForValue().get(Constants.Session.USER_SESSION_CACHE + token);
if (StringUtils.isEmpty(result)) {
log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] session data 未找到:sid:{},sessionValue:{}", token, result);
return null;
}
try {
SessionValue values = JSON.parseObject(result, SessionValue.class);
if (values == null) {
log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] session data 未找到:sid:{},sessionValue:{}", token, result);
return null;
}
SessionStruct sessionStruct = new SessionStruct();
sessionStruct.setSid(token);
sessionStruct.setValues(values);
return sessionStruct;
}catch (Exception ex){
LOGGER.error("序列化session出错", ex);
}catch (Exception e){
log.warn("[XyqbSessionContextHolder][getXSessionFromRedis] 序列化SessionValue出错:sid:{},sessionValue:{}", token, result, e);
return null;
}
}
......
......@@ -23,11 +23,12 @@ public class IPUtil {
* 172.16.0.0/16 - 公有云正式业务
* 172.20.0.0/16 - 3B私有云
* 172.30.0.0/16 - 3C私有云
* 172.41.0.0/16 - 3B,docker内网
*/
private static final Set<String> WHITE_ADDRESS = Sets.newHashSet();
private static final String LOCAL_ADDRESS = "127.0.0.1";
static {
String[] ips = {"172.16.", "172.20.", "172.30.", "192.168.3.", "192.168.4."};
String[] ips = {"172.16.", "172.20.", "172.30.", "172.41.", "192.168.3.", "192.168.4."};
WHITE_ADDRESS.addAll(Arrays.asList(ips));
//系统环境
if(!TechEnvironment.isPro()){
......
......@@ -22,13 +22,20 @@ public class ValidationUtil {
private static final String chineseNameExtendRegExp = "^[\u4dae\u4e00-\u9fff]+(\\.|·)?[\u4dae\u4e00-\u9fff]+$";
private static final String ipv4RegExp = "^((2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)\\.){3}(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)$";
private static final String localIpv4RegExp = "^((172\\.(1[0-6]|2[0-9]|3[01]))|(192\\.168|169\\.254)|((127|10)\\.(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)))(\\.(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)){2}$";
private static final String tokenRegExp = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
private static final Pattern phonePattern = Pattern.compile(phoneRegExp);
private static final Pattern chinesePattern = Pattern.compile(chineseNameRegExp);
private static final Pattern chineseExtendPattern = Pattern.compile(chineseNameExtendRegExp);
private static final Pattern ipv4Pattern = Pattern.compile(ipv4RegExp);
private static final Pattern localIpv4Pattern = Pattern.compile(localIpv4RegExp);
private static final Pattern tokenPattern = Pattern.compile(tokenRegExp);
/**
* 是否是合法的中国大陆手机号
* @param phoneNo
* @return
*/
public static boolean validatePhoneNo(String phoneNo) {
boolean lengthValid = StringUtils.isNotBlank(phoneNo) && phoneNo.length() == 11 && StringUtils.isNumeric(phoneNo);
if (!lengthValid) {
......@@ -38,6 +45,11 @@ public class ValidationUtil {
return matcher.find();
}
/**
* 是否是合法的中文姓名
* @param chinese
* @return
*/
public static boolean validateChinese(String chinese) {
if (StringUtils.isBlank(chinese)) {
return false;
......@@ -81,6 +93,19 @@ public class ValidationUtil {
return matcher.find();
}
/**
* 是否是合法的用户中心token
* @param token
* @return
*/
public static boolean validateToken(String token) {
if (StringUtils.isBlank(token)) {
return false;
}
Matcher matcher = tokenPattern.matcher(token);
return matcher.find();
}
/**
* 验证密令
* 私钥 + 操作 + 时
......
......@@ -6,8 +6,8 @@ import java.util.Base64;
public class TestStringCode {
public static void main(String[] args) {
System.out.println(ap_base64("13511112222", "000000"));
System.out.println(pc_base64("15566660006", "0000"));
System.out.println(ap_base64("18510236666", "123456"));
System.out.println(pc_base64("18222288391", "0000"));
}
final static String AUTHORIZATION = "authorization";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment