拾人牙慧篇之———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微信的第三方登录按照官方文档一步一步实习还是比较容易的,有什么问题可以交流交流。
以上用到的连接若是对该作者造成影响的,可以联系删掉。
拾人牙慧篇之———QQ微信的第三方登录实现的更多相关文章
- iOS微信实现第三方登录的方法
这篇文章主要介绍了iOS微信第三方登录实现的全过程,一步一步告诉大家iOS微信实现第三方登录的方法,感兴趣的小伙伴们可以参考一下 一.接入微信第三方登录准备工作.移动应用微信登录是基于OAuth2 ...
- Yii2 使用 QQ 和 Weibo 第三方登录源码
我们社区在 yii2-authclient 多次升级后,登录异常.一直想寻求一种通用的方法,尽量不重写 OAuth2, BaseOAuth 以及 OAuthToken 类, 所以本次直接在 initU ...
- Android通过微信实现第三方登录并使用OKHttp获得Token及源码下载
这里对于App在微信开放平台上申请AppID和secret在这里就略过了,我们微信的授权登录流程,腾讯官网给的流程如下: 1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用 ...
- CI框架 QQ接口(第三方登录接口PHP版)
本帖内容较多,大部分都是源码,要修改的地方只有一个,其他只要复制过去,就可以完美运行.本帖主要针对CI框架,不用下载SDK,按我下面的步骤,建文件,复制代码就可以了.10分钟不要,接口就可完成.第一步 ...
- 使用OAuth2.0协议的github、QQ、weibo第三方登录接入总结
目录 第三方接入总结 OAuth2.0介绍 github OAuth2.0登录接入 国内第三方应用商SDK使用 微博SDK 腾讯QQ SDK passport.js插件使用 安装 相关中间件.路由 返 ...
- Android 实现微信QQ分享以及第三方登录
集成准备 在微信开放平台创建移动应用,输入应用的信息,包括移动应用名称,移动应用简介,移动应用图片信息,点击下一步,选择Android 应用,填写信息提交审核. 获取Appkey 集成[友盟+]SDK ...
- qq 微信 微博 第三方分享
<html> <head> <meta charset="utf-8"> <meta name="viewport" ...
- QQ登录接口(第三方登录接口)
CI框架 QQ接口(第三方登录接口PHP版) 本帖内容较多,大部分都是源码,要修改的地方只有一个,其他只要复制过去,就可以完美运行.本帖主要针对CI框架,不用下载SDK,按我下面的步骤,建文件,复制代 ...
- nopCommerce 3.9 大波浪系列 之 微信公众平台登录插件
一.简介 插件源码下载:点击下载 微信公众平台网站授权帮助地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp142114084 ...
随机推荐
- 基于MSRDS机器人仿真平台的多机器人PID编队控制算法
自己调试的编队PID算法,效果也还可以,具体使用教程参考视频链接: http://v.youku.com/v_show/id_XMTUwNjc3NjMyNA 仿真中三个机器人保持编队,做直线运动,队形 ...
- Leetcode_26_Remove Duplicates from Sorted Array
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41558551 Remove Duplicates from ...
- python的read() 、readline()、readlines()、xreadlines()
先来一个小例子: import sys dir= os.path.dirname(os.path.abspath(__file__)) file_path='%s/test.txt' % dir f ...
- 【一天一道LeetCode】#54. Spiral Matrix
一天一道LeetCode系列 (一)题目 Given a matrix of m x n elements (m rows, n columns), return all elements of th ...
- Java序列化Serializable和Externalizable
纸上得来终觉浅,绝知此事要躬行 --陆游 问渠那得清如许,为有源头活水来 --朱熹 什么是Java序列化?为什么出现Java序列化?怎样实现Java序列化? 一.什么是Java序列化 ...
- Pixelmetrix :OTT Media Grinder (OTT TV 质量评价设备)
有关OTT TV 质量评价方法方面的研究少之又少.国内貌似还几乎没有相关的研究.不过在国外已经找到相关的产品了,翻译了一下产品手册的部分内容,很有参考价值,尤其是其提出的8个指标. 概述 OTT Me ...
- IntelliJ Idea + Maven + Junit
Caculate.java package com.yxj.TestJunit; /** * Created by ubd on 15-4-17. */ public class Caculate { ...
- Android For JNI(三)——C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值
Android For JNI(三)--C的指针,指针变量,指针常见错误,值传递,引用传递,返回多个值 C中比较难的这一块,大概就是指针了,所以大家还是多翻阅一下资料,当然,如果只是想了解一下,看本篇 ...
- (视频) 《快速创建网站》 3.2 WordPress多站点及Azure在线编辑器 - 扔掉你的ftp工具吧,修改代码全部云端搞定
本文是<快速创建网站>系列的第6篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 1. 网站管理平台WordPress和云计算平台Azure简介 (6分 ...
- 仿百度壁纸客户端(五)——实现搜索动画GestureDetector手势识别,动态更新搜索关键字
仿百度壁纸客户端(五)--实现搜索动画GestureDetector手势识别,动态更新搜索关键字 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Frag ...