当前位置: 首页 > 编程日记 > 正文

拾人牙慧篇之———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 οnkeydοwn="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;" οnclick="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());// 单点登录CookieCookie 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);// 用户CookieloginName = 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微信的第三方登录按照官方文档一步一步实习还是比较容易的,有什么问题可以交流交流。

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

转载于:https://www.cnblogs.com/minzhousblogs/p/6872510.html

相关文章:

win7旗舰版下配置IIS服务器

选择上述的插件后&#xff0c;Windows 需要更新一段时间&#xff0c;并重启电脑 测试是否安装成功&#xff1a;http://localhost 注意&#xff1a;默认端口号是 80&#xff0c;不能和tomcat 的 80 端口同时重启 常见问题&#xff1a; 1.默认页面或者新添加的网站一直出现…

微信小程序 加载中 动画效果

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 效果图&#xff1a; 代码&#xff1a; <view class"line"><image src"../../img/line.png"></image></view>.line {height:1px;position:absolute;animat…

java开放源码_开放源码的第一周:我是如何参与的,以及我学到的东西

java开放源码by Chak Shun Yu泽顺宇 开放源码的第一周&#xff1a;我是如何参与的&#xff0c;以及我学到的东西 (My first week of open source: how I got involved, and what I’ve learned) When I started to write this post, I had finished my first serious week of …

几个不错的开源的.net界面控件

转自原文 几个不错的开源的.net界面控件 (转) 几个不错的开源的.net界面控件 - zt 介绍几个自己觉得不错的几个开源的.net界面控件&#xff0c;不知道是否有人介绍过。 DockPanel Suite&#xff1a;开发类似VS.NET的界面&#xff0c;#Develop就是使用的这个控件。 网址&#…

CSS 盒子模型(转)

CSS中&#xff0c; Box Model叫盒子模型&#xff08;或框模型&#xff09;&#xff0c;Box Model规定了元素框处理元素内容&#xff08;element content&#xff09;、内边距&#xff08;padding&#xff09;、边框&#xff08;border&#xff09; 和 外边距&#xff08;margin…

React 入门笔记 1

React的核心&#xff1a;JSX 首先&#xff0c;React 的页面就是js文件&#xff0c;看到这会有朋友疑惑了&#xff0c;js怎么写标签组件&#xff1f; 解&#xff1a;首先&#xff0c;我们需要了解JSX&#xff0c;什么是JSX&#xff1f; JSX就是JavaScript XML。一种在React组件…

自学成才翁_如何发挥自学成才的内在游戏

自学成才翁by Victor Cassone由Victor Cassone 如何发挥自学成才的内在游戏 (How to play the inner game of self-taught development) Teaching yourself software development is hard. Anyone who tells you otherwise most likely hasn’t done it before.自学软件开发非…

C语言回溯算法解决N皇后问题

回溯算法的模型是 x, not satisfy ? x-- : continue. 代码中x作列号&#xff0c;y[x]保存第x列上皇后放置的位置。 1 #include<stdio.h>2 #include<math.h>3 #define N 54 int position_check(int,int*);5 void print_board(int count,int* y);6 int main()7 {8 …

React 创建组件 使用组件 2

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 组件&#xff1a; 通过组件&#xff0c;可以将UI拆分成独立的&#xff0c;可重复使用的部分&#xff0c;从概念上讲&#xff0c;组件就像javaScript函数&#xff0c;它们接受任意输入&#xff08;称之为…

如何征服Webpack 4并构建一个出色的React应用

This article has been outdated with the new release for babel, kindly check the updated article “How to combine Webpack 4 and Babel 7 to create a fantastic React app”, last updated October 13th, 2018本文与babel的新版本已经过时&#xff0c;请查看更新的文章…

React State和生命周期 3

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 一&#xff1a;组件的生命周期 组件的生命周期可分成三个状态&#xff1a; 安装&#xff1a;已插入真实DOM更新&#xff1a;正在被重新渲染卸载&#xff1a;已移出真实DOM 生命周期的方法有&#xff1a…

TCP/IP 笔记 1.3 IP:网际协议

---恢复内容开始--- I P是T C P / I P协议族中最为核心的协议。所有的 T C P、U D P、I C M P及I G M P数据都以I P数据报格式传输。  不可靠( u n r e l i a b l e)的意思是它不能保证 I P数据报能成功地到达目的地。 I P仅提供最好的传输服务。如果发生某种错误时&#xff…

keras bi-lstm_LSTM用于文本生成的应用介绍-使用Keras和启用GPU的Kaggle Kernels

keras bi-lstmby Megan Risdal梅根里斯达尔(Megan Risdal) LSTM用于文本生成的应用介绍-使用Keras和启用GPU的Kaggle Kernels (An applied introduction to LSTMs for text generation — using Keras and GPU-enabled Kaggle Kernels) Kaggle recently gave data scientists …

201521123013 《Java程序设计》第13周学习总结

1. 本周学习总结 2. 书面作业 Q1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn&#xff0c;分析返回结果有何不同&#xff1f;为什么会有这样的不同&#xff1f; ping值不同&#xff08;time列&#xff09;&#xff0c;cec.jmu.edu.cn的ping值比较小。ping值&am…

React 事件 4

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 将参数传递给事件处理程序 在循环内部&#xff0c;通常需要将额外的参数传递给事件处理程序。例如&#xff0c;如果id是行ID&#xff0c;则以下任何一个都可以工作&#xff1a; <button onClick{(e…

border-radius

周知&#xff1a;OPPO R819T Android 4.2.1和红米某些机型上&#xff0c;webview中&#xff0c;如果一个元素定义了 border border-radius&#xff0c;这时如果该元素有背景&#xff0c;那么背景将会溢出圆角之外&#xff0c;Yo新增了一个方法来fix这个问题&#xff0c;大家之…

javascript调试_如何提高JavaScript调试技能

javascript调试Almost all software developers who have written even a few lines of code for the Web have had at least a quick glance at JavaScript. After all, it is currently one of the most in-demand programming languages.几乎所有甚至为Web编写了几行代码的软…

Java transient

原文出自&#xff1a;http://www.importnew.com/21517.html 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口&#xff0c;这个对象就可以被序列化&#xff0c;java的这种序列化模式为开发者提供了很多便利&#xff0c;我们可以不必关系具体序列化的…

KBMMW 的日志管理器

kbmmw 4.82 最大的新特性就是增加了 日志管理器。 新的日志管理器实现了不同类型的日志、断言、异常处理、计时等功能。 首先。引用kbmMWLog.pas 单元后&#xff0c;系统就默认生成一个IkbmMWLog 实例&#xff1a; Log:IkbmMWLog; log 默认使用对应操作系统的日志功能。 为了能…

React 循环渲染 5

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 使用循环渲染的demo&#xff1a; const todoItems todos.map((todo) ><li key{todo.id}>{todo.text}</li> ); const todoItems todos.map((todo, index) >// Only do this if item…

面试时与人事交谈时间_如何与您的技术负责人交谈并解决通讯故障

面试时与人事交谈时间by Greg Sabo由格雷格萨博(Greg Sabo) 如何与您的技术负责人交谈并解决通讯故障 (How to talk to your tech lead and fix your communication glitches) Here’s where you messed up.这是你搞砸的地方。 Your tech lead told you to build out a new A…

inotify简介

一、inotify简介 inotify是Linux内核2.6.13 (June 18, 2005)版本新增的一个子系统&#xff08;API&#xff09;&#xff0c;它提供了一种监控文件系统&#xff08;基于inode的&#xff09;事件的机制&#xff0c;可以监控文件系统的变化如文件修改、新增、删除等&#xff0c;并…

链路层寻址与 ARP

一、 MAC 地址 不是主机或路由器具有链路层地址&#xff0c;而是它们的适配器&#xff08;即网络接口&#xff09;具有链路层地址。因此&#xff0c;具有多个网络接口的主机或路由器将具有与之相关联的多个链路层地址。 然而&#xff0c;链路层交换机并不具有与它们接口相关联的…

React 开始制作 6

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 从模拟开始 第1步&#xff1a;将UI分解为组件层次结构 不同的颜色为不同的组件&#xff0c; 第2步&#xff1a;在React中构建静态版本 第3步&#xff1a;确定UI状态的最小&#xff08;但完整&#xff…

php 空间类元素引入_引入单元素模式

php 空间类元素引入by Diego Haz迭戈哈兹(Diego Haz) 引入单元素模式 (Introducing the Single Element Pattern) 使用React和其他基于组件的库创建可靠的构建基块的规则和最佳实践。 (Rules and best practices for creating reliable building blocks with React and other …

Tcl学习之--列表|字典

【列表|字典】Tcl使用列表来处理各种集合&#xff0c;比方一个目录中的全部文件&#xff0c;以及一个组件的全部选项。最简单的列表就是包括由随意个空格、制表符、换行符、分隔的随意多个元素的字符串。比方: JerryAlice Mandy David l lindex命令: --> 获取元素 至少须要…

JAVA代码实现下载单个文件,和下载打包文件

//下载单个文件调用方法 /** * response * imgPath 下载图片地址 * fileName 保存下载文件名称 * date 2015年4月14日 下午5:53:24 */ public static void download(HttpServletResponse response,String imgPath,String fileName){ OutputStrea…

php读取本地xlsx格式文件的数据并按json格式返回

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 目的&#xff1a;php读取并操作本地xlsx格式的文件&#xff1b; 完整示例代码&#xff1a; 代码讲解&#xff1a;前端发起post网络请求&#xff0c;php接收一个name&#xff08;姓名&#xff09;的参数…

面向对象编程概念_如何向6岁的孩子解释面向对象的编程概念

面向对象编程概念by Alexander Petkov通过亚历山大佩特科夫(Alexander Petkov) Have you noticed how the same cliche questions always get asked at job interviews — over and over again?您是否注意到在求职面试中总是一遍又一遍地问同样的陈词滥调问题&#xff1f; I…

jQuery 属性

jQuery 属性 方法描述context在版本 1.10 中被废弃。包含被传递到 jQuery 的原始上下文jquery包含 jQuery 的版本号jQuery.fx.interval改变以毫秒计的动画运行速率jQuery.fx.off对所有动画进行全局禁用或启用jQuery.support包含表示不同浏览器特性或漏洞的属性集&#xff08;主…