知乎網站 OAuth 登錄彈窗是怎麼設計的?

1、彈窗登錄頁面為第三方網站,跨域情況下如何獲取彈窗的window屬性,如何判斷授權成功後關閉彈窗並刷新主頁面?用setInterval循環嗎?

2、若使用AngularJS ng-click是否能避免彈窗被瀏覽器攔截?


ng-click 能觸發打開。你可能需要同時支持兩種方式的 oauth 註冊:

- 彈出新窗口(window.open)

- 重定向方式 (location.href)

第一種體驗較好,第二種需要是因為環境有別,如 iOS Chrome 當前有兩個 bug:

- window.open 打開的子窗口中,opener 為 null

- CSP 除非設定為 `frame-src *`,window.open 才能成功打開窗口(由於第一個 bug 存在,這裡無意義)

重定向方式的註冊稍微需要多處理一些信息:

以查詢變數傳遞當前頁地址和回調地址 -&> 伺服器通過 cookie 保存起始地址 -&> 回調頁面讀取並清除起始地址 cookie,根據情況再設置 cookie 表示註冊待續 -&> 註冊頁恢復註冊,並清除 cookie。

另外,窗口間通訊的介面在此能通過返回值進行一點點互動,比如刷新頁面或跳轉。

補充點腳本容易理解:

起始頁:

app.factory "oauth", ($window, domainConfig) -&>
register: (serviceName) -&>
callbckUrl = "/oauth/callback"
urls =
qq: "#{domainConfig.qqOAuthUrl}?next=#{callbckUrl}"
sina: "#{domainConfig.sinaOAuthUrl}?next=#{callbckUrl}"

ua = navigator.userAgent
iOSChrome = /Mobile/.test(ua) and /CriOS/.test(ua)

url = urls[serviceName]
supportsWindowOpen = not iOSChrome
if supportsWindowOpen
$window.open url
else
$window.location.href = url + "from=" + encodeURIComponent($window.location.href)

回調頁:

var setUnfinished = function() {
document.cookie = "accountcallback="
+ "{{encodedJSON}}"
+ "; path=/"
}

if (window.opener) {
document.write(signedin ? "..." : "...")
if (signedin) {
opener.myApp.crossDomainMessage("accountcallback", accinfo)
} else if (snsinfo) {
var finished = opener.myApp.crossDomainMessage("accountcallback", snsinfo)
if (finished === false) {
setUnfinished()
opener.location.href = "/?next=" + opener.location.href
}
}
setTimeout(window.close, 500)
} else {
var url = "/"
if (from) {
if (signedin) {
location.href = from
return
} else {
url += "?next=" + from
}
}

if (!signedin snsinfo) {
setUnfinished()
}

location.href = url
}


推薦閱讀:

以worktile為例,怎麼分析AngularJs的架構方式呢?如果可以畫圖示之,感激不盡
AngularJS 於前端開發有什麼作用,對比其它框架有何優點?
angularjs項目需要從一個頁面跳轉到另一個頁面,同時需要傳遞一個參數。請問大神該通過什麼實現?
Web 前端開發需要使用 MVVM 框架嗎?
小菜鳥如何系統性學習React?

TAG:JavaScript | OAuth | 知乎技術實現 | AngularJS |