zoukankan      html  css  js  c++  java
  • 拾人牙慧篇之———QQ微信的第三方登录实现

    一、写在前面

        关于qq微信登录的原理之流我就不一一赘述了,对应的官网都有,在这里主要是展示我是怎么实现出来的,看了好几个博客,有的是直接复制官网的,有的不知道为什么实现不了。我只能保证我的这个是我实现后才贴出来的,本文有看不懂的地方请结合官网看。(话说我感觉我写博客废话好多)

    二、准备工作

        通过以下官网获得相应AppID和AppSecret以及对应的回调地址。

        QQ登录官网:https://connect.qq.com

        微信登录官网:https://open.weixin.qq.com

    三、登录实现第三方

    3.1、QQ授权登录实现

       这里的实现主要用JS_SDK来实现,通过这种实现回调地址基本没有什么用,区别于这种实现方式:如何在自己的网站上实现QQ授权登录?。步骤就不一一说了,直接上代码(红色部分为qq授权相关的,里面的appid和回调地址改成自己申请时候的既可)

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%String path = request.getContextPath() ;%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta charset="UTF-8">
    <title>登录页</title>
    <link href="<%=path%>/resource/css/public.css" rel="stylesheet" type="text/css" />
    <link href="<%=path%>/resource/css/index.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="<%=path%>/resource/js/tools/jquery-1.8.2.min.js"></script>
    <script type="text/javascript" src="<%=path%>/resource/js/tools/base.js"></script>
    <script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/openapi/qc_loader.js" 
    data-appid="1013XXXXX" 
    data-redirecturi="http://www.xxxxxx.com/qqlogincheck.jsp" 
    charset="utf-8">
    </script>
    <script type="text/javascript">
    var PATH ='<%=path%>';
    var FROM='${from}';
    jQuery(function(){
        loginEnterCheck();
    });
    function getOs(){
        var OsObject = "";
        if (navigator.userAgent.indexOf("MSIE") > 0) {
            return "MSIE";
        }
        if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0) {
            return "Firefox";
        }
        if (isSafari = navigator.userAgent.indexOf("Safari") > 0) {
            return "Safari";
        }
        if (isCamino = navigator.userAgent.indexOf("Camino") > 0) {
            return "Camino";
        }
        if (isMozilla = navigator.userAgent.indexOf("Gecko/") > 0) {
            return "Gecko";
        }
    }
    
    //回车键登陆,支持火狐和IE浏览器;
    function loginEnterCheck(){
          //获取当前浏览器;
          var browser = getOs();
          if(browser=="Firefox"){
              //判断IE还是火狐浏览器;
              $("html").die().live("keydown",function(event){     
                    if(event.keyCode==13){   
                        //调用登陆方法;
                        $(".J_login_btn").click();   
                    }     
              });   
          }else if(browser=="" || browser=="MSIE"){
              document.onkeydown=function(){
                  if(event.keyCode==13||event.which==13){ 
                       $(".J_login_btn").click();
                  }
              }
          }else{
              if(event.keyCode==13||event.which==13){ 
                     $(".J_login_btn").click();
                }
          }
    }
    
    function getInfo() {
        if(QC.Login.check()){
            QC.api("get_user_info")
                .success(function(s){//成功回调
                    QC.Login.getMe(function(openId, accessToken){
                        
                        var _data={loginName:s.data.nickname,openId:openId,otype:1,token:accessToken};
                        //console.log(_data);
                        $.ajax({
                            url:PATH+"/security/qqlogin.do",
                            type:"POST",
                            data:_data,
                            dataType:'json',
                            success:function(result) {
                                if(result.code==200){              
                                    //登录成功                                
                                       window.location.href=PATH+'/';
                                }else{
                                   if(result.code==101){
                                     $("#openId").val(result.openId);
                                     console.info(result);
                                     $("#loginName_qw").val(result.loginName);   
                                      var fm=document.getElementById("qqcheckForm");  
                                     // fm.action="";
                                      fm.submit(); 
                                    }
    
                                }
                            }
                        });
                     
                    })
                })
                .error(function(f){//失败回调
                    alert("获取用户信息失败!登录失败!");
                    location.href = "/security/toLoginPage.do";
                })
                .complete(function(c){//完成请求回调
                //alert("获取用户信息完成!");
                });
        }else{
            alert("请先登录qq!");
            location.href = "/security/toLoginPage.do";
        }
    }
    
    
    
    function qqlogin(){
        QC.Login({}, function (reqData, opts) {//登录成功
            getInfo();
        }, function (opts) {
            alert('注销成功');
        }
        );
        QC.Login.showPopup({
               appId:"10139XXXX",
               redirectURI:"http://www.xxxxxx.com/qqlogincheck.jsp"
            });
    }
    
    </script>
    
    <script type="text/javascript" src="<%=path%>/resource/js/login.js"></script>
    </head>
    <body onkeydown="loginEnterCheck();">
     <form method="post" action="<%=path%>/security/toQwRegisterPage.do" id="qqcheckForm">
     <input type="hidden" id="openId" name="openId">
      <input type="hidden" id="loginName_qw" name="loginName_qw">
      </form>  
    <div class="m_header">
        <div class='m_header_logo fix m_setWidth'>
            <a href='http://www.xxxxxx.com' class='m_logo'>
                <img src='<%=path%>/resource/images/logo.png' />
            </a>
            <span class='welcome_title'>欢迎登录</span>
        </div>
    </div>
    <div class="m_login_wrapper">
        <div class='m_login m_setWidth fix'>
            <div class='m_login_from'>
                <div class='m_login_box'>
                    <p class='m_login_title'>西玛会员</p>
                    <div class='m_login_input fix'>
                        <i class='m_login_user'></i>
                        <input name="loginName" type='text' placeholder='用户名' class='m_input J_user'/>
                    </div>
                    <div class='m_login_input fix'>
                        <i class='m_login_lock'></i>
                        <input name="password" type='password' placeholder='密码' class='m_input J_password'/>
                    </div>
                    <div class='m_login_handle fix'>
                        <span class='m_square_box c_switch checked'><span class='m_square'></span><i class='m_square_text'>自动登录</i></span>
                        <a href='<%=path%>/security/findPassword.do' class='m_forget_password'>忘记密码</a>
                    </div>
                    <button class='c_btn c_btn_green J_login_btn'>登录</button>
                    <div class='m_login_handle fix'>
                        <a >其他登录方式></a>
                    </div>
                            <div class='m_header_title_left '>
                        <a style="margin-right: 10px;" onclick="qqlogin()" >
                        <img src='<%=path%>/resource/images/login/btn_qzone.png' alt="QQ授权登录 " >
                        </a>
                        <a  style="margin-right: 10px;"  href="http://open.weixin.qq.com/connect/qrconnect?appid=wx1fbfXXXXXX&redirect_uri=http%3A%2F%2Fwww.xxxxxx.com%2Fsecurity%2FgetWebchatCode.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect">
                        <img src='<%=path%>/resource/images/login/btn_weixin.png' alt="微信授权登录 ">
                        </a>
                        </div>
                        
                    
                    <div class='m_to_register'>
                        <a href='<%=path%>/security/toRegisterPage.do'>免费注册></a>
                    </div>
    
                </div>
            </div>
        </div>
    </div>
    <jsp:include page="../public/buttom.jsp" flush="true" />
    </body>
    </html>

    这里用到的是 QC.Login.showPopup,期间遇到了showPopup 这种不能回调的情况,参考了:QC.Login.showPopup可有回调? 

    qq授权后台处理思路:通过点击qq登录,登录成功后回调,在回调中通过 QC.api("get_user_info")获取登录后的信息,在后台通过qq的openid来查询数据库,若是库中有值,则直接进入登录成功流程,若是没有值则跳转到手机号注册流程。(回调地址里面基本为空)

    3.2、微信授权登录实现

      上面代码的蓝色部分即为微信登录的连接,相应地方改成申请的既可.

      这里有三个地方需要注意:

      1、地址需要改成转义后的,%3A%2F%2F就等于://这样的形式。

      2、若是前面微信开放平台的是https,对应的回调也是https。

      3、这里写的回调地址是http://www.xxxxxx.com/security/getWebchatCode.do,但是微信申请里写http://www.xxxxxx.com既可。

      下面看看微信登录成功后的后台处理代码

    /**
         * 微信登录获取code
         */
        @RequestMapping(value = "/getWebchatCode.do")
        public ModelAndView getWebchatCode(HttpServletRequest request, HttpServletResponse response) {
            String code = request.getParameter("code");
            System.out.println("微信登录获取code=="+code);
            String url="https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret=XXX&code="+code+"&grant_type=authorization_code";
            
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("from", code);
            try {
            
                 JSONObject jb = HttpUtils.httpRequest(url,"GET",null);
                 System.out.println("通过code获取token=="+jb.toString());
                 String access_token= jb.getString("access_token");
                 
                 JSONObject userinfo = HttpUtils.httpRequest("https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+appid+"","GET",null);
                 System.out.println("通过token获取=="+userinfo.toString());
                 String loginName= userinfo.getString("nickname");
                 String openId=userinfo.getString("openid");
                 
    
                    Member member = memberService.selectOneByWeixinOpenId(openId);
                    if (member != null ) {//通过qq唯一openID判断该qq是否之前用过,同时判断loginName是否唯一
                        member.setLastLoginTime(new Date());
                        memberService.update(member);
                        // 设置线程变量
                        CurrentThreadContext.setValue(CurrentThreadContext.CURRENT_USER_ID, member.getId());
                        CurrentThreadContext.setValue(CurrentThreadContext.CURRENT_MEMBER, member);
                        CurrentThreadContext.setValue(CurrentThreadContext.CURRENT_MANAGE_SHOP_ID, member.getManageShopId());
                        // 单点登录Cookie
                        Cookie cookie_sso = new Cookie(CurrentThreadContext.COOKIES_LOGIN_KEY, AESUtil.encrypt(loginName,
                                        PropertiesUtil.getInstance().getValue("security.cipher.key")));
                        cookie_sso.setMaxAge(-1);
                        cookie_sso.setDomain(PropertiesUtil.getInstance().getValue("security.root.domain"));
                        cookie_sso.setPath("/");
                        response.addCookie(cookie_sso);
    
                        // 用户Cookie
                        loginName = DESUtil.strEnc(loginName, PropertiesUtil.getInstance().getValue("security.cipher.key"), "",
                                        "");
                        String shopFlage = "";
                        if (member.getManageShopId() != null) {
                            Shop t = new Shop();
                            t.setId(member.getManageShopId());
                            Shop shop = shopApiService.selectOne(t);
                            if (shop != null && shop.getStatus() != null
                                            && shop.getStatus().equals(ShopConstant.SHOP_STATUS_3)) {
                                shopFlage = member.getManageShopId().toString();
                            }
                        }
                        Cookie cookie_memberinfo = new Cookie(CurrentThreadContext.COOKIES_MEMBERINFO,
                                        loginName + "|" + shopFlage + "|" + member.getId());
                        cookie_memberinfo.setMaxAge(-1);
                        cookie_memberinfo.setDomain(PropertiesUtil.getInstance().getValue("security.root.domain"));
                        cookie_memberinfo.setPath("/");
                        response.addCookie(cookie_memberinfo);
                        map.put("code", "200");
                        map.put("msg", "登录成功");
                        return new ModelAndView("redirect:/",map);
                    } else {
                        //qq授权的不存在,跳转到输入手机验证码的地方
                        map.put("code", "101");
                        Member membertemp = memberService.selectOneByLoginName(loginName);
                        if(membertemp!=null){
                            map.put("loginName", loginName+"_xima"+new Random().nextInt(1000));
                        }else{
                            map.put("loginName", loginName);
                        }
                        map.put("wqType", "weixin");
                        map.put("openId", openId);
                    /*    map.put("msg", "用户名或密码不正确");*/
                        return new ModelAndView("security/qwRegister",map);
                        
                        
                    }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            return new ModelAndView("security/login",map);
        }

    主要是几次握手过程。

    四、总结

       qq微信的第三方登录按照官方文档一步一步实习还是比较容易的,有什么问题可以交流交流。

        以上用到的连接若是对该作者造成影响的,可以联系删掉。

  • 相关阅读:
    20000+关注,开源两本硬核的原创电子书!
    Tail Latency学习
    Zabbix5.0 监控redis
    JAVA多线程(九) ForkJoin框架
    JAVA多线程(八) Condition源码分析
    程序员英语学习(二) 标点符号对应的英语单词汇总
    linux shell快速入门
    Ubuntu常用指令和快捷键汇总
    Win10常用快捷键汇总
    算法路漫漫(三) 荷兰国旗
  • 原文地址:https://www.cnblogs.com/minzhousblogs/p/6872510.html
Copyright © 2011-2022 走看看