摘要:第三方登錄是現(xiàn)在常見的登錄方式,免注冊(cè)且安全方便快捷。大部分的第三方登錄都參考了的認(rèn)證方法。這里我主要總結(jié)一下第三方登錄組件的設(shè)計(jì)流程。身份認(rèn)證組件,需解耦,至少要喚起登錄和登出事件。認(rèn)證成功喚起登錄事件并將用戶信息傳遞出去。
第三方登錄是現(xiàn)在常見的登錄方式,免注冊(cè)且安全方便快捷。
本篇文章將以Github為例,介紹如何在自己的站點(diǎn)添加第三方登錄模塊。
OAuth2.0OAuth(開放授權(quán))是一個(gè)開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲(chǔ)的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用。
更多關(guān)于OAuth2.0的信息請(qǐng)?jiān)L問 OAuth 2.0 — OAuth
實(shí)際使用只需要知道:
提供方儲(chǔ)存了用戶的信息,ID,Name,Email等。
客戶端通過提供方指定的頁面發(fā)起請(qǐng)求,獲取token。
客戶端通過token獲得用戶信息。
Github詳細(xì)的認(rèn)證過程請(qǐng)?jiān)L問官方文檔 Authorization options for OAuth Apps,這里我對(duì)一般的web app請(qǐng)求認(rèn)證的過程做一下總結(jié)。
GIthub的具體認(rèn)證流程:
用戶點(diǎn)擊登錄按鈕跳轉(zhuǎn)至Github提供的授權(quán)界面,并提供參數(shù):客戶端ID(稍后會(huì)介紹到),回調(diào)頁面等。
GET https://github.com/login/oauth/authorize
參數(shù):
名稱 | 類型 | 描述 |
---|---|---|
client_id | string | 必需。GitHub的客戶端ID 。 |
redirect_uri | string | 回調(diào)地址,默認(rèn)返回申請(qǐng)時(shí)設(shè)置的回調(diào)地址。 |
scope | string | 以空格分隔的授權(quán)列表。eg:user repo 不提供則默認(rèn)返回這兩種。 |
state | string | 客戶端提供的一串隨機(jī)字符。它用于防止跨站請(qǐng)求偽造攻擊。 |
allow_signup | string | 如果用戶未注冊(cè)Github,是否提供注冊(cè)相關(guān)的信息,默認(rèn)是true。 |
通過驗(yàn)證后頁面跳轉(zhuǎn)至之前提供的回調(diào)頁面,url中包含相關(guān)參數(shù):code和state。
客戶端以POST的方式訪問GIthub提供的地址,提供參數(shù)code等。
POST https://github.com/login/oauth/access_token
參數(shù):
名稱 | 類型 | 描述 |
---|---|---|
client_id | string | 必需。GitHub的客戶端ID 。 |
client_secret | string | 必需。Github提供的一串隨機(jī)字符串。 |
code | string | 必需。上一步收到的code |
redirect_uri | string | 之前提供redirect_uri |
state | string | 之前提供的state |
Github返回?cái)?shù)據(jù), 包含accesstoken。根據(jù)不同的Accept標(biāo)頭返回不同格式,推薦json。
Accept: application/json {"access_token":"e72e16c7e42f292c6912e7710c838347ae178b4a", "scope":"repo,gist", "token_type":"bearer"}
客戶端以GET的方式訪問Github提供的地址,在參數(shù)中加入或在head中加入accesstoken。
GET https://api.github.com/user?access_token=...
curl -H "Authorization: token OAUTH-TOKEN" https://api.github.com/user
Github返回用戶的json數(shù)據(jù)。
大部分的第三方登錄都參考了Github的認(rèn)證方法。
Vue.js不用多說,Vue.js。這里我主要總結(jié)一下第三方登錄組件的設(shè)計(jì)流程。
組件以博客系統(tǒng)為例,可分為三類:
主頁,所有組件的parent。
身份認(rèn)證組件,需解耦,至少要喚起登錄和登出事件。
其他需要身份認(rèn)證的組件。
身份認(rèn)證組件(auth)組件的職能可概括為以下幾點(diǎn):
未登陸狀態(tài)時(shí)顯示登陸按鈕,登陸狀態(tài)時(shí)顯示注銷按鈕。
點(diǎn)擊登錄按鈕時(shí),頁面發(fā)生跳轉(zhuǎn)。
監(jiān)視地址欄有無code和正確state出現(xiàn)。如果出現(xiàn)開始身份認(rèn)證。
認(rèn)證成功喚起登錄事件并將用戶信息傳遞出去。
用戶點(diǎn)擊登出喚起登出事件。
更全面的,出于方便考慮以及Auth2.0的特性,accesstoken可以存放至cookie以實(shí)現(xiàn)一定時(shí)間內(nèi)免登陸且不用擔(dān)心密碼泄露。響應(yīng)的在用戶認(rèn)證成功和登出時(shí)需要對(duì)cookie進(jìn)行設(shè)置和清除操作。
那么開始最主要組件auth的編寫
首先進(jìn)行準(zhǔn)備工作,訪問Github -> settings -> Developer settings 填寫相關(guān)信息創(chuàng)建 Oauth App。
注意: 此處設(shè)置的 Authorization callback URL 即為客戶端的回調(diào)頁面??蛻舳松暾?qǐng)攜帶的參數(shù)與這個(gè)地址不同會(huì)報(bào)相應(yīng)的錯(cuò)誤。
得到client信息后就可以在auth組件內(nèi)設(shè)置字段了。
" @/components/GithubAuth.vue " data () { return { client_id: "your client ID", client_secret: "your client secret", scope: "read:user", // Grants access to read a user"s profile data. state: "your state", getCodeURL: "https://github.com/login/oauth/authorize", getAccessTokenURL: "/github/login/oauth/access_token", getUserURl: "https://api.github.com/user", redirectURL: null, code: null, accessToken: null, signState: false } }
模板中加入登錄按鈕, 保存之前的地址至cookie以便登錄后回調(diào),跳轉(zhuǎn)至授權(quán)頁面。
登錄
saveURL: function () { if (Query.parse(location.search).state !== this.state) { this.$cookie.set("redirectURL", location.href, 1) location.href = this.getCodeURL } }
A Vue.js plugin for manipulating cookies. ---vue-cookieParse and stringify URL. ---query strings
組件創(chuàng)建后,檢查地址欄是否存在有效code。如果存在則進(jìn)行相應(yīng)處理,獲取有效accesstoken存入cookie,頁面回調(diào)至登錄之前保存的地址。 如果不存在則檢查cookie內(nèi)是否存在accesstoken 獲取用戶信息。
注意: 需要計(jì)算得到的屬性務(wù)必在computed下定義。
computed: { formatCodeURL: function () { return this.getCodeURL + ("?" + Query.stringify({ client_id: this.client_id, scope: this.scope, state: this.state })) } }
created: function () { this.getCode() // when code in url if (this.code) this.getAccessToken() else { // if no code in top, get accessToken from cookie this.accessToken = this.$cookie.get("accessToken") if (this.accessToken) this.getUser() } }
獲取地址欄攜帶的code參數(shù)的處理:getCode()
getCode: function () { this.getCodeURL += ("?" + Query.stringify({ client_id: this.client_id, scope: this.scope, state: this.state })) let parse = Query.parse(location.search) if (parse.state === this.state) { this.code = parse.code } }
利用code獲取accesstoken的處理: getAccessToken()
getAccessToken: function () { this.axios.post(this.getAccessTokenURL, { client_id: this.client_id, client_secret: this.client_secret, code: this.code, state: this.state }).then((response) => { this.accessToken = response.data.access_token if (this.accessToken) { // save to cookie 30 days this.$cookie.set("accessToken", this.accessToken, 30) this.redirectURL = this.$cookie.get("redirectURL") if (this.redirectURL) { location.href = this.redirectURL } } }) }
A small wrapper for integrating axios to Vuejs. ---vue-axios
要說的是,因?yàn)閍xios是基于promise的異步操作,所以使用時(shí)應(yīng)當(dāng)特別注意。頁面跳轉(zhuǎn)放在回調(diào)函數(shù)里是為了防止promise還未返回時(shí)頁面就發(fā)生跳轉(zhuǎn)。
重要 :包括ajax,fetch在內(nèi)的向后臺(tái)提交資源的操作都存在跨域問題。瀏覽器同源政策及其規(guī)避方法(阮一峰)。 這里利用了代理的方法,使用vue-cli時(shí)可通過配置文件臨時(shí)設(shè)置代理規(guī)避跨域問題。在生產(chǎn)環(huán)境下需要配置服務(wù)器代理至其他域名。
" $/config/index.js " proxyTable: { "/github": { target: "https://github.com", changeOrigin: true, pathRewrite: { "^/github": "/" } }
/github會(huì)在請(qǐng)求發(fā)起時(shí)被解析為target。設(shè)置完成后中斷熱重載重新編譯,重新編譯,重新編譯。
利用accesstoken獲取用戶信息的處理:getUser()
getUser: function () { this.axios.get(this.getUserURl + "?access_token=" + this.accessToken) .then((response) => { let data = response.data this.signState = true // call parent login event this.$emit("loginEvent", { login: data.login, avatar: data.avatar_url, name: data.name }) }) // invaild accessToken .catch((error) => { console.log(error) this.$cookie.delete("accessToken") }) }
請(qǐng)求用戶信息成功后觸發(fā)了loginEvent事件,并以當(dāng)前用戶信息作為參數(shù)傳遞出去。
用戶登出的處理: logout()
注銷
logout: function () { this.$cookie.delete("accessToken") this.signState = false this.$emit("logoutEvent") }
清理cookie,觸發(fā)用戶登出事件。
主頁(app)引入auth組件并注冊(cè)為子組件。
import GithubAuth from "@/components/GithubAuth" Vue.component("auth", GithubAuth)
設(shè)置子組件觸發(fā)事件后的處理函數(shù)
methods: { login: function (user) { this.user = user }, logout: function () { this.user = null } }
初始化一個(gè)空的user字段后等待auth喚起事件,改變user字段的值。
data () { return { user: null } }其他組件
因?yàn)閂ue.js是響應(yīng)式的,props中設(shè)置user字段,初始化時(shí)傳入即可。
props: ["user"]結(jié)束語
以上僅是我個(gè)人總結(jié)出的一些方法,如有更好的解決方法或是錯(cuò)誤的地方請(qǐng)指出,感激不盡!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/93576.html
摘要:本文單純從簡單的技術(shù)實(shí)現(xiàn)來講,不涉及開放平臺(tái)的多維度的運(yùn)營理念。它的特點(diǎn)就是通過客戶端的后臺(tái)服務(wù)器,與服務(wù)提供商的認(rèn)證服務(wù)器進(jìn)行互動(dòng)能夠滿足絕大多數(shù)開放平臺(tái)認(rèn)證授權(quán)的需求。 本文單純從簡單的技術(shù)實(shí)現(xiàn)來講,不涉及開放平臺(tái)的多維度的運(yùn)營理念。 什么是開放平臺(tái) 通過開放自己平臺(tái)產(chǎn)品服務(wù)的各種API接口,讓其他第三方開發(fā)者在開發(fā)應(yīng)用時(shí)根據(jù)需求直接調(diào)用,例如微信登錄、QQ登錄、微信支付、微博登錄...
摘要:本文單純從簡單的技術(shù)實(shí)現(xiàn)來講,不涉及開放平臺(tái)的多維度的運(yùn)營理念。它的特點(diǎn)就是通過客戶端的后臺(tái)服務(wù)器,與服務(wù)提供商的認(rèn)證服務(wù)器進(jìn)行互動(dòng)能夠滿足絕大多數(shù)開放平臺(tái)認(rèn)證授權(quán)的需求。 本文單純從簡單的技術(shù)實(shí)現(xiàn)來講,不涉及開放平臺(tái)的多維度的運(yùn)營理念。 什么是開放平臺(tái) 通過開放自己平臺(tái)產(chǎn)品服務(wù)的各種API接口,讓其他第三方開發(fā)者在開發(fā)應(yīng)用時(shí)根據(jù)需求直接調(diào)用,例如微信登錄、QQ登錄、微信支付、微博登錄...
摘要:基礎(chǔ)簡要而言是一種安全機(jī)制用于應(yīng)用連接到身份認(rèn)證服務(wù)器獲取用戶信息并將這些信息以安全可靠的方法返回給應(yīng)用。這些信息被保存在身份認(rèn)證服務(wù)器以確保特定的客戶端收到的信息只來自于合法的應(yīng)用平臺(tái)。 OpenID Connect OpenID Connect簡介 OpenID Connect是基于OAuth 2.0規(guī)范族的可互操作的身份驗(yàn)證協(xié)議。它使用簡單的REST / JSON消息流來實(shí)現(xiàn),和...
摘要:前言基于做微服務(wù)架構(gòu)分布式系統(tǒng)時(shí),作為認(rèn)證的業(yè)內(nèi)標(biāo)準(zhǔn),也提供了全套的解決方案來支持在環(huán)境下使用,提供了開箱即用的組件。 前言 基于SpringCloud做微服務(wù)架構(gòu)分布式系統(tǒng)時(shí),OAuth2.0作為認(rèn)證的業(yè)內(nèi)標(biāo)準(zhǔn),Spring Security OAuth2也提供了全套的解決方案來支持在Spring Cloud/Spring Boot環(huán)境下使用OAuth2.0,提供了開箱即用的組件。但...
閱讀 1967·2021-09-30 09:46
閱讀 1376·2019-08-30 15:43
閱讀 1133·2019-08-29 13:28
閱讀 1933·2019-08-29 11:24
閱讀 1697·2019-08-26 13:22
閱讀 3981·2019-08-26 12:01
閱讀 1829·2019-08-26 11:33
閱讀 3252·2019-08-23 15:34