实习过程当中,我参与了web版相册管家的开发,负责登录页面的先后端逻辑。
须要在登录页接入QQ互联和微信扫码登录,并且是用页面内嵌方式。回头来看其实二者都有文档指导,步骤清楚,并不复杂。可是第一次接触不免踩坑,在此梳理以下,方便从此开发参考。css
开发文档 https://wiki.connect.qq.com/%E7%BD%91%E7%AB%99%E5%BA%94%E7%94%A8%E6%8E%A5%E5%85%A5%E6%B5%81%E7%A8%8Bhtml
appkey:appid对应的密钥,访问用户资源时用来验证应用的合法性。在OAuth2.0认证过程当中,appkey的值即为oauth_consumer_secret的值。
前端
tip: 申请时注意网站回调域必须为网站地址下的子目录,用户受权后页面会跳转到这个回调地址,一般状况下咱们须要取得该地址的code参数进行后续接入流程,因此要保证该地址中的代码可控。
vue
qq互联的受权流程以下图所示:
web
本文中列出的是server-side模式的登录流程,client-side模式可参考 https://wiki.connect.qq.com/%E5%BC%80%E5%8F%91%E6%94%BB%E7%95%A5_client-sidejson
tip:redirect_uri必须与注册应用的时候填的回调域同样,该项在申请经过后能够在qq互联应用管理处修改,无需再次审核。后端
参数正确后,该连接会显示QQ受权页,会自动检测PC端以及手机端登录过的qq帐号,并给出登录选项
浏览器
受权页登陆后,浏览器会自动跳转到回调地址,带上code参数,例如微信
http://localhost:3000/proxy?code=D21B82BA835586D8DF86135675EC71BD
此时,从url中取得code,进行下一步。app
tip:该code会在10分钟内过时,且没法重复使用
tip 3: 若想实现权限自动续期,参考 https://wiki.connect.qq.com/%E4%BD%BF%E7%94%A8authorization_code%E8%8E%B7%E5%8F%96access_token#Step2.EF.BC.9A.E9.80.9A.E8.BF.87AuthorizationCode.E8.8E.B7.E5.8F.96AccessToken
callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID","unionid":"YOUR_UNIONID"} );
使用access_token, appid, openid调用get_user_info接口,可获取用户信息。
UI要求实现的是相似于微云同样的内嵌登录框效果
我找了一圈,没发现qq互联有能够自定义生成登录界面或者登录二维码的操做(微信有),参考了几个内嵌登录的网站,发现你们的UI和大小都是固定的,猜测应该是经过iframe截取实现的,官方给的demo也是相似思路。
因而我本身琢磨着用iframe截取受权登录页面,而后经过iframe向父页面传值拿到code。怎么想这么搞都挺笨的,奈何没找到更简单的方法,抛砖引玉,若是有更方便的思路麻烦告知。
<div style="margin:0 auto;" v-if="isQQ"> <div style="width:360px;height:250px;overflow:hidden;border:0px;margin:0 auto; padding-top:30px;"> <div style="width:500px;height:800px;margin:-103px 0px 0px -95px;"> <iframe id="qq_login_frame" :src="iframeSrc" width="800" height="600" scrolling="no"> </iframe> </div> </div> </div>
截出来的效果以下:
mounted() { let codeUrl = window.location.href; let code = this.getCode(codeUrl) this.sendLoginCode(code) }, methods: { // 拆分url获取code getCode(url) { if (url.indexOf('code') !== -1) { let params = url.split('?')[1].split('&')[0].split('=')[1]; return (params); } }, // 发送给父页面 sendLoginCode(code) { window.parent.postMessage({ type: "sendCode", data: code }, '*'); }, }
// 监听iframe的返回 window.addEventListener('message', (e) => { console.log(e,e.data) let data = e.data; if(data && data.type && data.type == 'sendCode') { let code = data.data; this.getUserInfo(code) } }, false);
tip:注意!!! 微信应用的回调域和qq互联的不一样,举个例子,你的网站是http://a.com, qq互联的回调域只能是你申请时填写的http://a.com/login。可是,微信申请时的受权回调域填写你的主域名便可,由于
若是你申请微信的回调域也填写http://a.com/login,在生成受权页面时redirect_uri使用http://a.com/login会报错,并不能生成受权页面。
微信的受权登录流程与QQ互联基本相同,区别在于code以及access_token的有效期,以及code能够直接换取access_token+openid,在此再也不赘述,具体流程和接口可参考开发文档,以及接口文档 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316518&lang=zh_CN
先在页面中引入js文件(支持https)
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
var obj = new WxLogin({ self_redirect:true, id:"login_container", appid: "", scope: "", redirect_uri: "", state: "", style: "", href: "" });
参数列表以下:
.impowerBox .qrcode {width: 200px;} .impowerBox .title {display: none;} .impowerBox .info {width: 200px;} .status_icon {display: none} .impowerBox .status {text-align: center;}
按照本身的需求修改调整后,将样式代码转为base64加密,放入代码,这里我用的站长工具,你们自由发挥。
href:"data:text/css;base64,[加密后的样式代码]"