實習過程當中,我參與了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,[加密後的樣式代碼]"