package cn.regionsoft.trainingsaas.controller;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.regionsoft.one.admin.dto.OnlineUserDto;
import cn.regionsoft.one.admin.event.UserSessionListener;
import cn.regionsoft.one.annotation.Controller;
import cn.regionsoft.one.annotation.tag.Autowired;
import cn.regionsoft.one.annotation.tag.Cookies;
import cn.regionsoft.one.annotation.tag.Parameter;
import cn.regionsoft.one.annotation.tag.RequestMapping;import cn.regionsoft.one.caches.RedisUtil;
import cn.regionsoft.one.common.Constants;
import cn.regionsoft.one.common.JsonUtil;
import cn.regionsoft.one.common.Logger;
import cn.regionsoft.one.core.CommonUtil;
import cn.regionsoft.one.core.SystemContext;
import cn.regionsoft.one.core.auth.AdvancedSecurityProvider;
import cn.regionsoft.one.core.auth.LoginHelper;
import cn.regionsoft.one.core.auth.LoginResponseType;
import cn.regionsoft.one.core.auth.dto.LoginDto;
import cn.regionsoft.one.core.exception.BizException;
import cn.regionsoft.one.core.ids.IDGenerator;
import cn.regionsoft.one.enums.RequestMethod;
import cn.regionsoft.one.properties.ConfigUtil;
import cn.regionsoft.one.rpc.common.ServerConstant;
import cn.regionsoft.one.thridparty.wechat.WechatUserInfo;
import cn.regionsoft.one.web.core.ResourceResponse;
import cn.regionsoft.one.web.core.RespCode;
import cn.regionsoft.one.web.wrapper.ResourceResWrapper;import cn.regionsoft.trainingsaas.bizcache.CacheKey;
import cn.regionsoft.trainingsaas.dto.AuthResultDto;
import cn.regionsoft.trainingsaas.dto.UserDetailDto;
import cn.regionsoft.trainingsaas.entity.SpRegisterValidate;
import cn.regionsoft.trainingsaas.enums.SpMemberRegType;
import cn.regionsoft.trainingsaas.resource.SpRegisterValidateResource;
import cn.regionsoft.trainingsaas.resource.WechatResource;
import cn.regionsoft.trainingsaas.resource.impl.SpRegisterValidateResourceImpl;
import cn.regionsoft.trainingsaas.resource.impl.WechatResourceImpl;@Controller
@RequestMapping("/wechat")
public class WechatController {
public static Logger logger = Logger.getLogger(WechatController.class);
@Autowired(targetClass = WechatResourceImpl.class)
private WechatResource wechatResource;
@Autowired(targetClass = SpRegisterValidateResourceImpl.class)
private SpRegisterValidateResource spRegisterValidateResource;
/**
* 微信oauth2登录接口
* @param code
* @param httpResponse
* @return
*/
private static final String WECHAT_INDEX_PAGE = "wechat_index_page";
private static final String WECHAT_INVITE_CODE_PAGE = "wechat_invite_code_page";
private final static String INVITE_CODE_CACHE_COOKIE ="invite_code_check";
@RequestMapping(value = "/auth" ,method ={RequestMethod.POST,RequestMethod.GET},responseHeader= {"Content-Type == application/json;charset=UTF-8"})
public String auth(@Parameter(value = "code") String code,@Parameter(value = "state") String state,HttpServletRequest httpRequest,HttpServletResponse httpResponse) {
ResourceResponse<?> result = null;
try {
String ip = CommonUtil.getRequestIp(httpRequest);
if(state==null)throw new Exception("invalid access by null state");
logger.debug("state="+state);
String[] stateArray = state.split(Constants.DOT_SPLITER);
String appId = stateArray[0];
String preWechatLoginToken = stateArray[1];
//防止重复提交及攻击
String val = RedisUtil.delAtomic(CacheKey.WECHAT_LOGIN_SECURE_SEEDS_CACHE_KEY+preWechatLoginToken);
if(val==null) {
//非法登录
throw new Exception("invalid access");
}
ResourceResponse<AuthResultDto> authResponse = wechatResource.auth(appId,code,ip);
if(authResponse.isSuccess()==false) {
return JsonUtil.objectToJson(authResponse);
}
else {
AuthResultDto authResultDto = authResponse.getData();
if(!authResultDto.isSuccess()) {//登录认证失败
WechatUserInfo wechatUserInfo = authResultDto.getWechatUserInfo();
SpMemberRegType spMemberRegType = authResultDto.getSpMemberRegType();
if(spMemberRegType== SpMemberRegType.INVITE_CODE) {
logger.debug("redirect invite code");
String inviteCodeToken = String.valueOf(IDGenerator.generateSnowflakeID());
int expireSeconds = 180;//3分钟过期
RedisUtil.set(CacheKey.INVITE_CODE_DATA_KEY+inviteCodeToken, JsonUtil.parseToJson(wechatUserInfo), expireSeconds);
Cookie inviteCodeFlag = new Cookie(INVITE_CODE_CACHE_COOKIE,inviteCodeToken);
inviteCodeFlag.setMaxAge(expireSeconds);
inviteCodeFlag.setPath(Constants.PATH_DELIMETER);
inviteCodeFlag.setHttpOnly(true);
httpResponse.addCookie(inviteCodeFlag);
httpResponse.sendRedirect(ConfigUtil.getProperty(WECHAT_INVITE_CODE_PAGE));
}
else if(spMemberRegType== SpMemberRegType.INVITE_PHONE) {
//TODO
System.out.println(2);
}
return "secondCheck";
}
}
UserDetailDto userDetailDto = authResponse.getData().getUserDetailDto();
//认证成功则写入cookie 和广播登录信息,并跳转页面
this.onAccountCreated(userDetailDto, httpRequest, httpResponse);
logger.debug("redirect");
httpResponse.sendRedirect(ConfigUtil.getProperty(WECHAT_INDEX_PAGE));
} catch (Exception e) {
logger.error(e);
result = ResourceResWrapper.failResult(e.getMessage(), null, RespCode._508);
}return "hello";
}
//认证成功则写入cookie 和广播登录信息,并跳转页面
private void onAccountCreated(UserDetailDto userDetailDto,HttpServletRequest httpRequest,HttpServletResponse httpResponse) throws IOException {
String sessionId = String.valueOf(IDGenerator.generateSnowflakeID());
Map<String,String> claims = new HashMap<String,String>();
claims.put(LoginHelper.CLAIM_SESSION_ID, sessionId);
String token = LoginHelper.generateToken(claims);
LoginDto loginDto = new LoginDto();
loginDto.setValidAccount(true);
loginDto.setSessionId(sessionId);
loginDto.setToken(token);
loginDto.setLoginResponseType(LoginResponseType.LOGIN_SUCCESSFULLY);
AdvancedSecurityProvider securityProvider = SystemContext.getInstance().getAdvancedSecurityProvider();
if(securityProvider!=null){
loginDto.setUserInfoJson(JsonUtil.objectToJson(securityProvider.getAccessableGroupsByAccount(userDetailDto.getAccount())));
}
else{
loginDto.setUserInfoJson(null);
}
Date now = CommonUtil.now();
OnlineUserDto onlineUserDto = new OnlineUserDto();
onlineUserDto.setAccount(userDetailDto.getAccount());
onlineUserDto.setIp(CommonUtil.getRequestIp(httpRequest));
onlineUserDto.setLoginTime(now);
onlineUserDto.setLastActiveTime(now);
onlineUserDto.setSessionId(loginDto.getSessionId());
onlineUserDto.setSpId(Long.valueOf(userDetailDto.getLoginSpId()));
UserSessionListener.Event loginEvent = new UserSessionListener.Event(new UserSessionListener.EventData(UserSessionListener.Event.LOGIN, onlineUserDto));
loginEvent.publishSync();
LoginHelper.addLoginFlag(loginDto.getUserInfoJson(),httpResponse);
LoginHelper.addToken(token,httpResponse);
}
@RequestMapping(value = "/pre-wechat-login" ,method ={RequestMethod.POST,RequestMethod.GET},responseHeader= {"Content-Type == application/json;charset=UTF-8"})
public String preWechatLogin(HttpServletResponse httpResponse) {
try {
String preWechatLoginToken = String.valueOf(IDGenerator.generateSnowflakeID());
int expireSeconds = 10;
RedisUtil.set(CacheKey.WECHAT_LOGIN_SECURE_SEEDS_CACHE_KEY+preWechatLoginToken, "1", expireSeconds);Map<String,String> result = new HashMap<String,String>(2);
result.put("preToken", preWechatLoginToken);
result.put("prodMode", ConfigUtil.getProperty("prod.mode"));
return JsonUtil.objectToJson(ResourceResWrapper.successResult(result));
} catch (Exception e) {
return JsonUtil.objectToJson(ResourceResWrapper.failResult(e.getMessage(), RespCode._508));
}
}
@RequestMapping(value = "/empty" ,method ={RequestMethod.POST,RequestMethod.GET},responseHeader= {"Content-Type == application/json;charset=UTF-8"})
public String empty() {
try {
return JsonUtil.objectToJson(ResourceResWrapper.successResult(Constants.OK));
} catch (Exception e) {
return JsonUtil.objectToJson(ResourceResWrapper.failResult(e.getMessage(), RespCode._508));
}
}
@RequestMapping(value = "/verify-invite-code" ,method ={RequestMethod.POST,RequestMethod.GET},responseHeader= {"Content-Type == application/json;charset=UTF-8"})
public String verifyInviteCode(@Parameter(value = "inviteCode") String inviteCode,
@Cookies Map<String,String> cookies,HttpServletResponse httpResponse,HttpServletRequest httpRequest) {
try {
String val = RedisUtil.get(CacheKey.INVITE_CODE_CACHE_KEY+inviteCode);
if(val==null) {
return JsonUtil.objectToJson(ResourceResWrapper.failResult("邀请码错误或已过期", RespCode._200));
}
String inviteCodeToken = cookies.get(INVITE_CODE_CACHE_COOKIE);
//防止重复提交及攻击
String wechatUserInfoJson = RedisUtil.delAtomic(CacheKey.INVITE_CODE_DATA_KEY+inviteCodeToken);
if(wechatUserInfoJson==null) {
throw new BizException("invalid access");
}
WechatUserInfo wechatUserInfo = JsonUtil.jsonToBean(wechatUserInfoJson, WechatUserInfo.class);
ResourceResponse<Integer> response = spRegisterValidateResource.checkCode(val,wechatUserInfo.getSpId(),inviteCode);
Integer resultCode = response.getData();if(resultCode==null) {
return JsonUtil.objectToJson(ResourceResWrapper.failResult("邀请码错误或已过期", RespCode._200));
}
String ip = CommonUtil.getRequestIp(httpRequest);
ResourceResponse<UserDetailDto> authResponse = wechatResource.autoRegister(wechatUserInfo, ip, Long.valueOf(wechatUserInfo.getSpId()),inviteCode);
if(authResponse.isSuccess()==false) {
return JsonUtil.objectToJson(authResponse);
}
else {
onAccountCreated(authResponse.getData(), httpRequest, httpResponse);
}
return JsonUtil.objectToJson(ResourceResWrapper.successResult(null));
} catch (Exception e) {
return JsonUtil.objectToJson(ResourceResWrapper.failResult(e.getMessage(), RespCode._508));
}
}
@RequestMapping(value = "/performanceTest" ,method ={RequestMethod.POST,RequestMethod.GET},responseHeader= {"Content-Type == application/json;charset=UTF-8"})
public String performanceTest(HttpServletRequest httpRequest) {
return "hello";
}}
微信登录回调
最新推荐文章于 2024-05-09 22:40:44 发布