package com.yc.sdk.oauth2.action; import java.io.File; import java.io.IOException; import java.util.UUID; import java.util.concurrent.TimeUnit; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.qq.connect.QQConnectException; import com.qq.connect.api.OpenID; import com.qq.connect.api.qzone.UserInfo; import com.qq.connect.javabeans.AccessToken; import com.qq.connect.javabeans.qzone.UserInfoBean; import com.qq.connect.oauth.Oauth; import com.riversoft.weixin.common.oauth2.OpenUser; import com.riversoft.weixin.common.user.Gender; import com.yc.action.BaseAction; import com.yc.entity.AttachmentConfig; import com.yc.entity.UserAccountEntity; import com.yc.exception.CallBackMessage; import com.yc.multiData.SpObserver; import com.yc.sdk.oauth2.entity.OAuth2InfoEntity; import com.yc.sdk.oauth2.service.OAuth2UserIfc; import com.yc.sdk.password.action.ChangePassword; import com.yc.sdk.shopping.util.SettingKey; import com.yc.sdk.weixincp.util.AvatarFile; import com.yc.sdk.weixincp.util.RandomString; import com.yc.service.user.UserAccountServiceIfc; import com.yc.utils.SessionKey; import me.chanjar.weixin.common.util.http.URIUtil; @Controller public class OAuth2ForQQ extends BaseAction { @Autowired private OAuth2UserIfc oauth2UserIfc; @Autowired private UserAccountServiceIfc userAccountService; @SuppressWarnings("rawtypes") @Autowired RedisTemplate redisTemplate ; protected static String oauth2HostName = AttachmentConfig.get("Oauth2.HostName") ; @SuppressWarnings("unchecked") @RequestMapping("/oauth2/qq.do") public void action(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html;charset=utf-8"); HttpSession session = request.getSession(); String code = request.getParameter("code") ; String dbid = request.getParameter(SessionKey.DATA_BASE_ID) ; String hostUrl = SettingKey.getHostUrl(request) ; //取当前原始主机名, CallBackMessage callBackMessage=new CallBackMessage(); String redirect = request.getParameter("redirect"); // 登录后重定向页面,Added by Johns Wang, 2016-02-17 if (redirect != null && !"".equals(redirect)) redirect = URIUtil.encodeURIComponent(redirect); if (code == null || "".equals(code)) { String oauth2UUID = UUID.randomUUID().toString().toUpperCase();//生成uuid String orgHost = request.getParameter("orghost") ; String authorizationUserCode = request.getParameter(SessionKey.OAUTH2AuthorizationUserCode) ; try { if (authorizationUserCode!=null && !"".equals(authorizationUserCode) && authorizationUserCode.length() > 50) { authorizationUserCode = ChangePassword.getDecryptPassword(authorizationUserCode); } }catch (Exception e) { e.printStackTrace(); System.out.println(this.getClass()+ " :参数" +SessionKey.OAUTH2AuthorizationUserCode + " 解密错误"); this.print(response, callBackMessage.sendErrorMessage("错误:"+ (e.getCause()!=null?e.getCause().getMessage(): e.getMessage()))); return ; } String dialogUrl = "" ; try { dialogUrl = new Oauth(request).getAuthorizeURL(request) ; } catch (QQConnectException e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage("错误:"+ (e.getCause()!=null?e.getCause().getMessage(): e.getMessage()))); return ; }catch (Exception e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage("错误:"+ (e.getCause()!=null?e.getCause().getMessage(): e.getMessage()))); return ; } //将关键信息保存到 redis 集群中,以确保数据交换时的信息安全 OAuth2InfoEntity oauth2InfoEntity = new OAuth2InfoEntity() ; oauth2InfoEntity.setDbid(dbid); oauth2InfoEntity.setOrgHost(orgHost); oauth2InfoEntity.setRedirect(redirect); oauth2InfoEntity.setOauth2From("qq"); oauth2InfoEntity.setAuthorizationUserCode(authorizationUserCode); try { //将 OAuth2InfoEntity 对象保存到 redis 服务器中 ,保留 1800秒 ,30分钟 redisTemplate.delete(oauth2UUID) ; redisTemplate.opsForValue().set(oauth2UUID, oauth2InfoEntity, 1800, TimeUnit.SECONDS); boolean result = true ; if (!result) { this.print(response, callBackMessage.sendErrorMessage("写入 redis 集群服务时出错,请检查集群服务配置!")); return ; } session.setAttribute(SessionKey.OAUTH2UUID, oauth2UUID); }catch(Exception e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage (e.getCause()!=null?e.getCause().getMessage(): e.getMessage())); return ; } try { response.sendRedirect(dialogUrl); } catch (IOException e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage (e.getCause()!=null?e.getCause().getMessage(): e.getMessage())); return ; } //this.print(response, ""); callBackMessage.setRedirect(dialogUrl); this.print(response, callBackMessage.toString() ); return ; } //String state = request.getParameter("state"); //String rand = (String)session.getAttribute("state") ; try { //配置信息保存在 qqconnectconfig.properties 文件中 AccessToken accessTokenObj = (new Oauth(request)).getAccessTokenByRequest(request); if (accessTokenObj.getAccessToken().equals("")) { //我们的网站被CSRF攻击了或者用户取消了授权 //做一些数据统计工作 没有获取到响应参数 this.print(response, callBackMessage.sendErrorMessage("登录异常,拉取用户信息失败,请检查拉取用户的域名和QQ connect中设置是否一致!")); return ; }else{ String oauth2UUID = (session.getAttribute(SessionKey.OAUTH2UUID)==null?"":(String)session.getAttribute(SessionKey.OAUTH2UUID)); //request.getParameter("uuid") ; if (oauth2UUID == null || "".equals(oauth2UUID)) { this.print(response, callBackMessage.sendErrorMessage("非法访问!")); return ; } OAuth2InfoEntity oauth2InfoEntity = null ; try{ //从 redis 服务器中取出 OAuth2InfoEntity 对象 oauth2InfoEntity = (OAuth2InfoEntity) redisTemplate.opsForValue().get(oauth2UUID) ; }catch(Exception e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage (e.getCause()!=null?e.getCause().getMessage(): e.getMessage())); return ; } if (oauth2InfoEntity == null) { this.print(response, callBackMessage.sendErrorMessage("从redis服务器获取原始主机信息失败,请检查【"+(oauth2HostName==null?"":oauth2HostName) +"】与当前登录主机是否使用同一个redis集群服务")); return ; } String orgHost = oauth2InfoEntity.getOrgHost(); //原始主机名 if (orgHost == null || "".equals(orgHost)) { this.print(response, callBackMessage.sendErrorMessage("非法原始主机名")); return ; } String accessToken = null,openId = null; //long tokenExpireIn = 0L; accessToken = accessTokenObj.getAccessToken(); //tokenExpireIn = accessTokenObj.getExpireIn(); //session.setAttribute("demo_access_token", accessToken); //session.setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn)); // 利用获取到的accessToken 去获取当前用的openid -------- start OpenID openIDObj = new OpenID(accessToken); openId = openIDObj.getUserOpenID(); //PrintWriter out = response.getWriter(); //out.println("欢迎你,代号为 " + openID + " 的用户!"+"
"); UserInfo qzoneUserInfo = new UserInfo(accessToken, openId,request); UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo(); if (userInfoBean.getRet() == 0) { String dbId = oauth2InfoEntity.getDbid(); try { SpObserver.setDBtoInstance("_" + dbId);// 切换数据源 OpenUser openUser = new OpenUser() ; openUser.setOpenId(openId); openUser.setHeadImgUrl(userInfoBean.getAvatar().getAvatarURL100()); openUser.setNickName(userInfoBean.getNickname()); int genderCode = 0 ; if (userInfoBean.getGender()!=null&&"男".equals(userInfoBean.getGender())) genderCode = 1 ; if (userInfoBean.getGender()!=null&&"女".equals(userInfoBean.getGender())) genderCode = 2 ; openUser.setSex(Gender.fromCode(genderCode)); OpenUser erpOpenUser = oauth2UserIfc.getOpenUserFromQQ(openId) ; if (erpOpenUser == null) { //保存新用户 erpOpenUser = oauth2UserIfc.saveQQUser(openUser) ; } //更新头像 if (erpOpenUser != null && openUser.getHeadImgUrl() != null && (!openUser.getHeadImgUrl().equals(erpOpenUser.getHeadImgUrl()) || erpOpenUser.getAvatarUnid()==null || erpOpenUser.getAvatarUnid().equals("") )) { String filePath = session.getServletContext().getRealPath("/") + "uploads" + File.separator + "smallpic" + File.separator; String fileName = RandomString.getRandomString(8) + ".jpg"; File file = AvatarFile.getAvatarFile(openUser.getHeadImgUrl(), fileName, filePath); // 获取微信图像 oauth2UserIfc.saveQQUserAvator(openUser, Integer.valueOf(dbId), file) ;// 上传图像文件至数据库 } oauth2InfoEntity.setOpenId(openId); oauth2InfoEntity.setNickName(userInfoBean.getNickname()); oauth2InfoEntity.setHeadimgurl(userInfoBean.getAvatar().getAvatarURL100()); try { //将 OAuth2InfoEntity 对象保存到 redis 服务器中 ,保留 1800秒 ,30分钟 redisTemplate.delete(oauth2UUID) ; redisTemplate.opsForValue().set(oauth2UUID, oauth2InfoEntity, 1800, TimeUnit.SECONDS); boolean result = true ; if (!result) { this.print(response,callBackMessage.sendErrorMessage( "写入 redis 集群服务时出错,请检查集群服务配置!")); return ; } }catch(Exception e) { e.printStackTrace(); this.print(response,callBackMessage.sendErrorMessage (e.getCause() !=null?e.getCause().getMessage(): e.getMessage())); return ; } //根据扫码openid 获取用户信息 UserAccountEntity userAccount = userAccountService.getUserInfoByOauth2OpenIdForQQ(openId); //直接登录 String goUrl = orgHost+"/oauth2/login.do?"+SessionKey.OAUTH2UUID+"="+ oauth2UUID; if (userAccount==null) { if (oauth2InfoEntity!=null && oauth2InfoEntity.getAuthorizationUserCode()!=null&&!"".equals(oauth2InfoEntity.getAuthorizationUserCode())) { //直接绑定用户名 oauth2UserIfc.saveOpenIdToUserCodeForQQ(oauth2InfoEntity.getAuthorizationUserCode(),openId) ; // this.print(response, callBackMessage.sendSuccessMessage("绑定QQ用户成功,请使用QQ扫码登录!")); this.print(response, "
绑定QQ用户成功,请使用QQ扫码登录!
"); return ; }else { //绑定用户名,然后再登录 goUrl = hostUrl + "/oauth2/buildinguser.jsp?"+SessionKey.OAUTH2UUID+"="+ oauth2UUID+"&oauth2from=qq" ; } } response.sendRedirect(goUrl) ; return ; }catch (Exception e) { throw e ; }finally { SpObserver.setDBtoInstance(); } /* out.println(userInfoBean.getNickname() + "
"); out.println(userInfoBean.getGender() + "
"); out.println("黄钻等级: " + userInfoBean.getLevel() + "
"); out.println("会员 : " + userInfoBean.isVip() + "
"); out.println("黄钻会员: " + userInfoBean.isYellowYearVip() + "
"); out.println("
"); out.println("
"); out.println("
");*/ } else { this.print(response, callBackMessage.sendErrorMessage("很抱歉,我们没能正确获取到您的QQ信息,原因是: " + userInfoBean.getMsg())); return ; } } } catch (QQConnectException | IOException e) { e.printStackTrace(); this.print(response, callBackMessage.sendErrorMessage((e.getCause() !=null?e.getCause().getMessage(): e.getMessage()))); }catch (Exception e) { e.printStackTrace(); this.print(response,callBackMessage.sendErrorMessage( (e.getCause() !=null?e.getCause().getMessage(): e.getMessage()))); } } }