微信登录回调

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";
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值