QQ第三方登录 SpringMVC + Spring data JPA + Freemark

1、HTML页面
			<div class="formRow other">
                            <p>第三方登录</p>
                            <ul class="clear">
                                <li>
                                    <a href="${path}/login/qqLogin"><img src="${resources}/images/login/qq.png"></a>
                                </li>
                                <li>
                                    <a href=""><img src="${resources}/images/login/wb.png"></a>
                                </li>
                                <li>
                                    <a href="${path}/login/wxLogin"><img src="${resources}/images/login/wx.png"></a>
                                </li>
                            </ul>
                        </div>

2、调转到登录方法,会根据Oauth2.0协议规范调,调用getAuthorizeURL方法return返回authorizeURL,并带上相应参数

	/**
	 * QQ用户第三方登录页面
	 * @throws IOException 
	 */
	@RequestMapping(value="/qqLogin",method = RequestMethod.GET)
	public void qqLogin(Model model,HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
            		response.sendRedirect(new Oauth().getAuthorizeURL(request));
        	} catch (QQConnectException e) {
            		e.printStackTrace();
        	}
	}

3、QQ第三方登录中SDK源代码,返回authorizeURL
 
public String getAuthorizeURL(ServletRequest request)throws QQConnectException
  {
    String state = RandomStatusGenerator.getUniqueState();
    ((HttpServletRequest)request).getSession().setAttribute("qq_connect_state", state);
    String scope = QQConnectConfig.getValue("scope");
    if ((scope != null) && (!scope.equals(""))) {
      return getAuthorizeURL("code", state, scope);
    }
    return QQConnectConfig.getValue("authorizeURL").trim() + "?client_id=" + QQConnectConfig.getValue("app_ID").trim() + "&redirect_uri=" + QQConnectConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state;
  }


4、根据返回的返回authorizeURL,跳到指定的回调地址,

              如果之前用第三方QQ成功登录过,根据该登录QQ的信息找到与之绑定的会员信息,存到session中,并返回index首页,

              如果之前没有用第三方QQ登录过,则进入绑定页面bindfirst


	/**
	 * QQ第三方登录之后,获取qq相关信息之后的跳转
	 */
	@RequestMapping(value="/qqLoginAfter",method=RequestMethod.GET)
	public String qqLoginAfter(Model model,Member member,ThirdMember thirdMember,HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
            String accessToken   = null,
                   openID        = null;
            long tokenExpireIn = 0L;

            if (accessTokenObj.getAccessToken().equals("")) {
            	// 我们的网站被CSRF攻击了或者用户取消了授权,做一些数据统计工作
                System.out.print("没有获取到响应参数");
            } else {
                accessToken = accessTokenObj.getAccessToken();
                tokenExpireIn = accessTokenObj.getExpireIn();

                request.getSession().setAttribute("demo_access_token", accessToken);
                request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));

                // 利用获取到的accessToken 去获取当前用的openid -------- start
                OpenID openIDObj =  new OpenID(accessToken);
                openID = openIDObj.getUserOpenID();

                request.getSession().setAttribute("demo_openid", openID);
                // 利用获取到的accessToken 去获取当前用户的openid --------- end

                UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
                UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
                
                /**
                 * 1、通过openID和状态判断是否有对应的第三方登录会员的这条记录
                 * 2、如果存在该条记录,进入网站首页。
                 * 3、如果不存在,进获取获取用户信息,先进入绑定账号页面,可已绑定以前注册过的,也可以当前进行注册,然后再绑定。
                 * 		绑定成功之后,member表里面插入一条数据,third_member第三方登录表里面也插入一天数据,并且关联member_id
                 */
                Boolean hasthirdmember = thirdMemberService.findByOpenIdAndStatus(openID,StatusEnum.NORMAL.getValue());
                if(hasthirdmember){
                	thirdMember = thirdMemberService.findThirdMemberByOpenIdAndStatus(openID,StatusEnum.NORMAL.getValue());
                	member = memberService.get(thirdMember.getMember().getId());
                	request.getSession().setAttribute("loginMember", member);
                	return "redirect:/index";
                }else{
                	request.getSession().setAttribute("openID", openID);
                	request.getSession().setAttribute("userInfoBean", userInfoBean);
                	String headurl = userInfoBean.getAvatar().getAvatarURL100(); //头像 100*100
            		model.addAttribute("headurl", headurl);
                	return "bindfirst";
                }
            }
        } catch (QQConnectException e) {
        	logger.error("很抱歉,我们没能正确获取到您的信息", e);
        }
        return "redirect:/index";
    }


5、已经有热点账号,点击绑定,调用绑定的方法

		<div class="sub">
                    <p>已经有热点账号?立即去<a href="${path}/index/qqLoginAfterBDSPage">绑定账号</a></p>
                </div>


6、进入绑定页面

	/**
	 * QQ第三方登录之后的跳转进入绑定页面 --有账号,绑定操作---页面
	 */
	@RequestMapping(value="/qqLoginAfterBDSPage",method=RequestMethod.GET)
		public String qqLoginAfterBDSPage() throws Exception {
        	return "bindsecond";
	}
	


7、进入绑定页面,调用AJAX,提交要绑定的账号信息

		//---------------QQ绑定已有账号----------------
			function bind(){
				$.ajax({
					type:"post",
					url:"${path}/index/qqLoginAfterBDSecond",
					data:$("#bind-form").serialize(),
					success:function(data){
						if(data.code==200){
							common.alert({content:data.msg});
							window.location.href="${path}/index";
						}else{
							common.alert({content:data.msg});
						}
					},
					error: function(XMLHttpRequest, textStatus, errorThrown) {
	               			common.alert({content:'网络异常'});
	               			}
	            		})
			}

8、绑定方法,绑定成功之后,保存第三方登录QQ的信息


	/**
	 * QQ第三方登录之后的跳转进入绑定页面 --有账号,绑定操作
	 */
	@RequestMapping(value="/qqLoginAfterBDSecond",method=RequestMethod.POST)
	@ResponseBody
	public ResultObject qqLoginAfterBDSecond(Model model,String username,String password,ThirdMember thirdMember,HttpServletRequest request, HttpServletResponse response) throws Exception {
		Member member =null;
		if(CommonUtil.isPhone(username)){
			member = memberService.findMemberByPhone(username);
			if (member == null) {
				return new ResultObject("500", "该账号不存在", "");
			}
		}else if(CommonUtil.isEmail(username)){
			member = memberService.findMemberByEmail(username);
			if (member == null) {
				return new ResultObject("500", "该账号不存在", "");
			}
		}else{
			member = memberService.findMemberByUsername(username);
			if(member == null){
				return new ResultObject("500", "该账号不存在", null);
			}
		}
		//判断账户 密码
		boolean flagUsername =( member != null );
		if (!flagUsername) {
			return new ResultObject("500", "用户名不存在", "");
		}	
		boolean flagPassword =(member.getPassword().equals(MD5.toMD5(password)) );
		if (!flagPassword) {
			return new ResultObject("500", "密码错误", "");
		}	
		//判断账户状态
		if(member.getStatus()!=StatusEnum.NORMAL.getValue()){
			return new ResultObject("300", "会员已经被停用", "");
		}
		String openID = (String) request.getSession().getAttribute("openID");
		UserInfoBean userInfoBean = (UserInfoBean) request.getSession().getAttribute("userInfoBean");
		String nickname = userInfoBean.getNickname();                //昵称
		String headurl = userInfoBean.getAvatar().getAvatarURL100(); //头像 100*100
        	String sex = userInfoBean.getGender();                       //性别
        	/*-------------得到openID 昵称,姓名,性别,头像,类型,保存到第三方登录的数据库表中----------------*/
        	int sexNum =0 ;
       		if(sex.equals("男")){
        		sexNum = 1;
        	}else if(sex.equals("女")){
        		sexNum = 2;
        	}else{
        		sexNum = 0;
       		}
        	thirdMember.setThirdType(1);
        	thirdMember.setOpenId(openID);
        	thirdMember.setMember(member);
        	thirdMember.setName(nickname);
        	thirdMember.setSex(sexNum);
        	thirdMember.setHeadUrl(headurl);
        	thirdMember.setStatus(StatusEnum.NORMAL.getValue());
        	thirdMember.setCreateTime(new Date());
        
        	thirdMemberService.save(thirdMember);
        
        	request.getSession().setAttribute("loginMember", member);
        
        	return new ResultObject("200", "绑定成功", "");
	}

9、如果没有热点账号,就直接注册,注册完成提交之后的同时进行绑定

		/* ---------------- 注册 ---------------- */
			function register(){
			if($('#reg_form').valid()){
				$.ajax({
					type:"post",
					url:"${path}/reg/qqLoginAfterbindReg",
					data:$("#bind_first").serialize(),
					success:function(data){
						if(data.code==200){
							window.location.href="${path}/index";
						}else{
							common.alert({content:data.msg});
						}
					},
					error: function(XMLHttpRequest, textStatus, errorThrown) {
		               		common.alert({content:'网络异常'});
		               		}
		            	})
		         	}
			}

10、注册并且绑定的方法,成功之后,保存会员注册相关信息,并保存第三方登录QQ的信息,同时把该会员存到session中,并返回index首页,

/**
	 * QQ第三方登录之后的跳转进入绑定页面--没有账号,注册绑定操作
	 */
	@RequestMapping(value="/qqLoginAfterbindReg",method=RequestMethod.POST)
	@ResponseBody
	public ResultObject qqLoginAfterbindReg(Member member,@ModelAttribute("memberInfo") MemberInfo memberInfo,ThirdMember thirdMember,
			String random,RedirectAttributes redirectAttributes,HttpServletRequest request){
		try {
			/** -------- redis获取验证码 -------- **/
			String randomInRedis = redisService.get("redis_login_"+member.getPhone());
			if(randomInRedis != null && !randomInRedis.equals(random)){
				return new ResultObject("500", "短信验证码错误", null);
			}
			
			/** -------- 获取QQ用户相关信息 -------- **/
			String openID = (String) request.getSession().getAttribute("openID");
			UserInfoBean userInfoBean = (UserInfoBean) request.getSession().getAttribute("userInfoBean");
			String nickname = userInfoBean.getNickname();                //昵称
			String headurl = userInfoBean.getAvatar().getAvatarURL100(); //头像 100*100
	        	String sex = userInfoBean.getGender();                       //性别
	        	/*-------------得到openID 昵称,姓名,性别,头像,类型,保存到第三方登录的数据库表中----------------*/
	        	int sexNum =0 ;
	        	if(sex.equals("男")){
	        		sexNum = 1;
	        	}else if(sex.equals("女")){
	        		sexNum = 2;
	        	}else{
	        		sexNum = 0;
	        	}
	        	thirdMember.setThirdType(1);
	        	thirdMember.setOpenId(openID);
	        	thirdMember.setMember(member);
	        	thirdMember.setName(nickname);
	        	thirdMember.setSex(sexNum);
	        	thirdMember.setHeadUrl(headurl);
	        	thirdMember.setStatus(StatusEnum.NORMAL.getValue());
	        	thirdMember.setCreateTime(new Date());
			
	        	/** -------- 把获取的QQ用户的头像,性别,昵称保存到会员相关的表中-------- **/
	        	member.setHeadUrl(headurl);
	        	memberInfo.setSex(sexNum);
	        
			/** -------- 会员注册-------- **/
			ResultObject rs = memberService.register(member,memberInfo);
			/** -------- 第三方登录表中保存数据-------- **/
	       	 	thirdMemberService.save(thirdMember);
	        
			//登录
			request.getSession().setAttribute("loginMember", member);
			
			//记录地理位置
			recordService.saveMemberLocationRecord(member,request);
		    
			return rs;
		} catch (Exception e) {
			logger.error("注册出错", e);
			return new ResultObject("500", "注册出错", null);
		}
	}

附加:

1、需要引入QQ第三方登录的jar包

		<!-- QQ登录-->
		<dependency>
    			<groupId>net.gplatform</groupId>
    			<artifactId>Sdk4J</artifactId>
    			<version>2.0</version>
		</dependency>

2、需要引入QQ第三方登录SDK文档中的配置文件,里面包含app_ID、app_KEY、redirect_URI、scope等相关信息



QQ互联API列表

QQ互联SDK下载

使用说明:1.直接引入Sdk4J.jar 包至项目工程内。

2.修改qqconnectconfig.properties 文件,在指定修改的地方填写自己app的相关信息和要获取的scope权限(前4行信息)注意不要试图修改api的请求地址,

这里之所以暴露出来是为了方便兼容以后的变动。

3.将qqconnectconfig.properties文件放到自己的项目的context ClassLoader的可以加载的目录下,一般放在项目的src目录即可。

4.查看demo程序,结合api doc文档,进行接口的调用。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值