Commit c5c3f0a6 authored by 王亮's avatar 王亮

finished behavior qt.

parent c414a844
......@@ -37,7 +37,9 @@ public interface Constants {
String X_AUTH_FROM = "qg-registered-from";
String X_BEHAVIOR_TYPE = "qg-behavior-type";
String X_BEHAVIOR_ID = "qg-behavior-id";
String X_BEHAVIOR_IMAGEVALUE = "qg-behavior-imageValue";
int VERIFICATION_LEN = 2;
int SMS_CODE_LEN_4 = 4;
int SMS_CODE_LEN_6 = 6;
......
package cn.quantgroup.xyqb.config.http;
import cn.quantgroup.xyqb.filter.BehaviorInterceptor;
import cn.quantgroup.xyqb.filter.TokenInterceptor;
import cn.quantgroup.xyqb.service.captcha.IQuantgroupCaptchaService;
import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import org.springframework.stereotype.Component;
......@@ -20,6 +24,8 @@ public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Autowired
private ISessionService sessionService;
@Autowired
private IQuantgroupCaptchaService quantgroupCaptchaService;
@Override
public void addFormatters(FormatterRegistry registry) {
......@@ -46,6 +52,9 @@ public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TokenInterceptor(sessionService)).addPathPatterns("/v2/**");
registry.addInterceptor(new TokenInterceptor(sessionService)).addPathPatterns("/v2/**")
.excludePathPatterns("/v2/behavior/code");
registry.addInterceptor(new BehaviorInterceptor(quantgroupCaptchaService)).addPathPatterns("/v2/**","/api/v2")
.excludePathPatterns("/v2/behavior/code");
}
}
\ No newline at end of file
......@@ -11,4 +11,7 @@ public class UserConstant {
public static final String defaultTenantIdString = "560761";
public static final String defaultAppId = "560761";
public static final String IMAGE_FORMAT_PNG = "png";
public static final String IMG_BASE64_PATTREN = "data:image/" + IMAGE_FORMAT_PNG + ";base64,%s";
}
package cn.quantgroup.xyqb.constant.enums;
/**
*
*/
public enum VerifyTypeEnum {
NONE,GT,QG
}
package cn.quantgroup.xyqb.controller.req.v2;
import cn.quantgroup.xyqb.model.ClientType;
import cn.quantgroup.xyqb.model.SettingType;
import lombok.Data;
@Data
public class BehaviorReq {
/**
* 1:极验,2: 量化派图形验证码
*/
private Integer type;
/**
* 手机号码
*/
private String phone;
/**
* 0:h5,1:web,2:app
* @see ClientType
*/
private String clientType;
/**
* 0:账密,1:短验;
* @see SettingType
*/
private Integer settingType;
private String ip;
}
package cn.quantgroup.xyqb.controller.v2;
import cn.quantgroup.xyqb.controller.req.v2.BehaviorReq;
import cn.quantgroup.xyqb.model.BehaviorCodeBean;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.service.v2.BehaviorContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v2/behavior")
public class BehaviorV2Controller {
@Autowired
private BehaviorContext behaviorContext;
/**
* 统一获取行为验证码
* @return JsonResult<SMSCodeBean>
* @see <a href="http://yapi.quantgroups.com/project/17/interface/api/65824">统一获取行为验证码</a>
*/
@PostMapping("/code")
public JsonResult<BehaviorCodeBean> getCode(@RequestBody BehaviorReq behaviorReq){
return JsonResult.buildSuccessResultGeneric(behaviorContext.generate(behaviorReq));
}
}
......@@ -4,7 +4,6 @@ import cn.quantgroup.xyqb.controller.req.v2.LoginReq;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.LoginBean;
import cn.quantgroup.xyqb.service.v2.LoginContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
......@@ -20,6 +19,12 @@ public class OauthV2Controller {
this.loginContext = loginContext;
}
/**
* 对外统一登录接口
* @param loginReq LoginReq
* @return JsonResult<LoginBean>
* @see <a href="http://yapi.quantgroups.com/project/17/interface/api/65699">对外统一登录接口</a>
*/
@PostMapping("/login")
public JsonResult<LoginBean> login(@RequestBody LoginReq loginReq){
return JsonResult.buildSuccessResultGeneric(loginContext.login(loginReq));
......
package cn.quantgroup.xyqb.controller.v2;
import cn.quantgroup.xyqb.controller.req.v2.LoginReq;
import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.LoginBean;
import cn.quantgroup.xyqb.model.SMSCodeBean;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v2/sms")
public class SMSV2controller {
/**
* 统一获取短信验证码
* @return JsonResult<SMSCodeBean>
* @see <a href="http://yapi.quantgroups.com/project/17/interface/api/65709">统一获取短信验证码</a>
*/
@PostMapping("/code")
public JsonResult<SMSCodeBean> getCode(){
return null;
}
/**
* 统一验证短信验证码
* @return JsonResult<Boolean>
* @see <a href="http://yapi.quantgroups.com/project/17/interface/api/65829">...</a>
*/
@PostMapping("/verify")
public JsonResult<Boolean> verify(){
return null;
}
}
......@@ -12,9 +12,13 @@ public enum BizExceptionEnum {
UN_EXIT_REGISTERED_FROM("1001","租户id不存在"),
UN_AUTHORIZED("1002","请先登录"),
UN_EXIT_USER("1003","用户不存在"),
ERROR_PASSWORD("1004","用户名或者密码错误");
ERROR_PASSWORD("1004","用户名或者密码错误"),
// 验证码相关20开头
FAIL_GENERATE_IMAGE("2001","生成图片失败"),
FAIL_VERIFY_CODE("2002","图形验证码错误"),
UN_EXIT_VERIFY_TYPE("2003","不存在的验证码方式");
......
package cn.quantgroup.xyqb.filter;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.exception.BizException;
import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.service.captcha.IQuantgroupCaptchaService;
import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.session.XyqbSessionContextHolder;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashSet;
public class BehaviorInterceptor implements HandlerInterceptor {
private final IQuantgroupCaptchaService quantgroupCaptchaService;
public BehaviorInterceptor(IQuantgroupCaptchaService quantgroupCaptchaService){
this.quantgroupCaptchaService = quantgroupCaptchaService;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String type = request.getHeader(Constants.X_BEHAVIOR_TYPE);
if(StringUtils.isEmpty(type) || !StringUtils.isNumeric(type)){
return true;
}
switch (Integer.parseInt(type)){
case 1:
//走极验逻辑
return false;
case 2:
//走量化派图形验证逻辑
String id = request.getHeader(Constants.X_BEHAVIOR_ID);
String imageValue = request.getHeader(Constants.X_BEHAVIOR_IMAGEVALUE);
boolean result = quantgroupCaptchaService.validQuantgroupCaptcha(id,imageValue);
if(result){
return true;
}else{
throw new BizException(BizExceptionEnum.FAIL_VERIFY_CODE);
}
default:
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
XyqbSessionContextHolder.releaseSession();
}
}
package cn.quantgroup.xyqb.model;
import lombok.Builder;
import lombok.Data;
/**
* 生成行为验证码的时候,
*/
@Data
public class BehaviorCodeBean {
/**
* 0:极验,1: 量化派图形验证码
* 当客户端给的是极验,但是由于极验不可用的时候,会返回降级量化派图形验证码
*/
private Integer type;
private QtCode qtCode;
private GeetestCode geetestCode;
@Data
@Builder
public static class QtCode {
private String imageId;
private String imageData;
}
@Data
public static class GeetestCode{
}
}
......@@ -24,9 +24,6 @@ public enum ClientType {
public static ClientType valueByName(String name) {
name = Optional.ofNullable(name).orElse("").toLowerCase();
switch (name) {
case "app":
case "native":
return APP;
case "h5":
return H5;
case "web":
......@@ -36,4 +33,15 @@ public enum ClientType {
}
}
public static ClientType valueByName(Integer code) {
switch (code) {
case 0:
return H5;
case 1:
return WEB;
default:
return APP;
}
}
}
package cn.quantgroup.xyqb.model;
import lombok.Data;
@Data
public class SMSCodeBean {
}
......@@ -29,4 +29,14 @@ public enum SettingType {
}
}
public static SettingType valueByCode(Integer code) {
switch (code) {
case 1:
return SMSLOGIN;
default:
return PASSWD;
}
}
}
package cn.quantgroup.xyqb.service.v2;
import cn.quantgroup.xyqb.controller.req.v2.BehaviorReq;
import cn.quantgroup.xyqb.exception.BizException;
import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import cn.quantgroup.xyqb.model.BehaviorCodeBean;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class BehaviorContext {
private final Map<Integer,BehaviorStrategy> behaviorStrategyMap = new HashMap<>();
public BehaviorContext(List<LoginStrategy> loginStrategies, List<BehaviorStrategy> behaviorStrategies) {
behaviorStrategies.forEach(i->behaviorStrategyMap.put(i.getType(), i));
}
public BehaviorCodeBean generate(BehaviorReq behaviorReq){
BehaviorStrategy behaviorStrategy = behaviorStrategyMap.get(behaviorReq.getType());
if(behaviorStrategy == null){
throw new BizException(BizExceptionEnum.UN_EXIT_VERIFY_TYPE);
}
return behaviorStrategy.generate(behaviorReq);
}
}
package cn.quantgroup.xyqb.service.v2;
import cn.quantgroup.xyqb.controller.req.v2.BehaviorReq;
import cn.quantgroup.xyqb.controller.req.v2.LoginBehavior;
import cn.quantgroup.xyqb.model.BehaviorCodeBean;
public interface BehaviorStrategy {
Integer getType();
boolean validate(LoginBehavior loginBehavior);
void checkParam(LoginBehavior loginBehavior);
BehaviorCodeBean generate(BehaviorReq behaviorReq);
}
package cn.quantgroup.xyqb.service.v2;
import cn.quantgroup.xyqb.controller.req.v2.BehaviorReq;
import cn.quantgroup.xyqb.controller.req.v2.LoginBehavior;
import cn.quantgroup.xyqb.model.BehaviorCodeBean;
import org.springframework.stereotype.Service;
/**
* 极验模式
*/
@Service
public class GeetestBehaviorStrategy implements BehaviorStrategy{
@Override
public Integer getType() {
return 0;
return 1;
}
@Override
......@@ -20,4 +24,11 @@ public class GeetestBehaviorStrategy implements BehaviorStrategy{
public void checkParam(LoginBehavior loginBehavior) {
}
@Override
public BehaviorCodeBean generate(BehaviorReq behaviorReq) {
return null;
}
}
......@@ -13,11 +13,9 @@ import java.util.Map;
public class LoginContext {
private final Map<Integer, LoginStrategy> loginStrategyMap = new HashMap<>();
private final Map<Integer,BehaviorStrategy> behaviorStrategyMap = new HashMap<>();
public LoginContext(List<LoginStrategy> loginStrategies,List<BehaviorStrategy> behaviorStrategies) {
public LoginContext(List<LoginStrategy> loginStrategies) {
loginStrategies.forEach(i -> loginStrategyMap.put(i.getType(), i));
behaviorStrategies.forEach(i->behaviorStrategyMap.put(i.getType(), i));
}
public LoginBean login(LoginReq loginReq) {
......@@ -25,15 +23,8 @@ public class LoginContext {
LoginStrategy loginStrategy = loginStrategyMap.get(loginReq.getType());
BaseLoginParam loginParam = loginStrategy.checkParam(loginReq);
//第二步、进行行为验证
if(loginReq.getBehavior()!=null){
BehaviorStrategy behaviorStrategy= behaviorStrategyMap.get(loginReq.getBehavior().getType());
behaviorStrategy.checkParam(loginReq.getBehavior());
}
//第三步、执行登录操作
LoginBean loginBean = loginStrategy.login(loginParam);
//第二步、执行登录操作
return loginStrategy.login(loginParam);
......
package cn.quantgroup.xyqb.service.v2;
import cn.quantgroup.xyqb.controller.req.v2.BehaviorReq;
import cn.quantgroup.xyqb.controller.req.v2.LoginBehavior;
import cn.quantgroup.xyqb.exception.BizException;
import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import cn.quantgroup.xyqb.model.BehaviorCodeBean;
import cn.quantgroup.xyqb.service.captcha.IQuantgroupCaptchaService;
import cn.quantgroup.xyqb.thirdparty.jcaptcha.AbstractManageableImageCaptchaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.Locale;
import java.util.Map;
/**
* 公司自有验证码模式
*/
public class QuantGroupBehaviorStrategy implements BehaviorStrategy{
@Service
@Slf4j
public class QuantGroupBehaviorStrategy implements BehaviorStrategy {
@Autowired
@Qualifier("customCaptchaService")
private AbstractManageableImageCaptchaService imageCaptchaService;
@Autowired
@Qualifier("stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Autowired
private IQuantgroupCaptchaService quantgroupCaptchaService;
@Override
public Integer getType() {
return 1;
return 2;
}
@Override
......@@ -20,4 +47,15 @@ public class QuantGroupBehaviorStrategy implements BehaviorStrategy{
public void checkParam(LoginBehavior loginBehavior) {
}
@Override
public BehaviorCodeBean generate(BehaviorReq behaviorReq) {
BehaviorCodeBean behaviorCodeBean = new BehaviorCodeBean();
Map<String, String> challenge = quantgroupCaptchaService.fetchQuantgroupCaptcha(Locale.CHINA);
if (challenge == null) {
throw new BizException(BizExceptionEnum.FAIL_GENERATE_IMAGE);
}
behaviorCodeBean.setQtCode(BehaviorCodeBean.QtCode.builder().imageId(challenge.get("imageId")).imageData(challenge.get("image")).build());
return behaviorCodeBean;
}
}
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