前言
最近公司讓我做一下客戶端如何接入OAuth2.0服務(wù)器認(rèn)證的實(shí)例給客戶,本身對(duì)這塊不是很熟悉老玛,上網(wǎng)找了很多資料,這里把我的成果記錄一下钧敞。這篇文章主要還是講項(xiàng)目實(shí)現(xiàn),概念的學(xué)習(xí)感覺還學(xué)的不到家溉苛,準(zhǔn)備整理整理再寫。
項(xiàng)目實(shí)現(xiàn)主要還是參考了阮一峰老師的《理解OAuth 2.0》吧愚战,大家可以學(xué)習(xí)這一篇文章齐遵,對(duì)于OAuth2講的很詳細(xì)。
過程實(shí)現(xiàn)
下面是接入的過程梗摇,實(shí)現(xiàn)的授權(quán)模式是最常用的授權(quán)碼(Authorization code)模式的接入方式。
OAuth服務(wù)器
既然我們要實(shí)現(xiàn)的是接入OAuth2的過程伶授,必不可少的就是OAuth2的服務(wù)器,這里我選擇用github提供的服務(wù)作為一個(gè)oAuth2服務(wù)器流纹,讓github作為OAuth2服務(wù)器的步驟如下。
Vue實(shí)現(xiàn)
1. 對(duì)接環(huán)境配置
項(xiàng)目的配置文件放置于路徑:src/config/config.js
具體配置:
var config={
//請(qǐng)求授權(quán)地址
userAuthorizationUri:"https://github.com/login/oauth/authorize",
//accessToken請(qǐng)求地址
accessTokenUri : "https://github.com/login/oauth/access_token",
//用戶信息請(qǐng)求地址
userInfoUri:"https://api.github.com/user",
//登出請(qǐng)求地址
logoutUri:"https://github.com/logout",
//項(xiàng)目地址
localuri :"http://localhost:9999",
//回調(diào)地址
redirect_uri : "http://localhost:9999/login",
//案例資源服務(wù)器地址
resUri:"http://localhost:8080",
//客戶端相關(guān)標(biāo)識(shí)疮蹦,請(qǐng)從認(rèn)證服務(wù)器申請(qǐng)
clientId: "",
client_secret:"",
//申請(qǐng)的權(quán)限范圍
scope:"user",
//可選參數(shù)茸炒,客戶端的當(dāng)前狀態(tài)愕乎,可以指定任意值壁公,用于校驗(yàn)感论,此次案例不做相關(guān)認(rèn)證
state:"",
//一些固定的請(qǐng)求參數(shù)
response_type:"token",
grant_type : "authorization_code",
code:"",
}
export default config;
2. 用戶登錄并獲取Access_Token
-
登錄贮尖,配置客戶端信息并重定向到認(rèn)證地址趁怔,等待用戶授權(quán)湿硝。
文件地址:src/util/loginUtils.js login:function (vue) { vue.$config.code = RndNum(4); var authorUrl = vue.$config.userAuthorizationUri; authorUrl = authorUrl + ('?' + vue.$querystring.stringify({ client_id:vue.$config.clientId, response_type:vue.$config.response_type, scope:vue.$config.scope, state:vue.$config.state, redirect_uri:vue.$config.redirect_uri, })) window.location.href = authorUrl; } 其中幾個(gè)參數(shù)的含義: response_type:表示授權(quán)類型润努,必選項(xiàng)关斜,此處的值固定為"code" client_id:表示客戶端的ID铺浇,必選項(xiàng) redirect_uri:表示重定向URI痢畜,可選項(xiàng) scope:表示申請(qǐng)的權(quán)限范圍鳍侣,可選項(xiàng) state:表示客戶端的當(dāng)前狀態(tài)丁稀,可以指定任意值倚聚,認(rèn)證服務(wù)器會(huì)原封不動(dòng)地返回這個(gè)值。
這一步的目的是取得用戶的授權(quán)并得到授權(quán)碼惑折,授權(quán)碼將用于取得Access_Token授账。
如果配置了參數(shù)中的redirect_uri,取得授權(quán)碼之后認(rèn)證服務(wù)器將會(huì)重定向到該地址白热。
-
用戶完成授權(quán),取得授權(quán)碼屋确,我們將攜帶授權(quán)碼和配置相關(guān)信息向認(rèn)證服務(wù)器申請(qǐng)Access_Token
文件地址:src/components/ssologin.vue mounted:function () { this.code = this.$route.query.code; this.state = this.$route.query.state; this.getToken(); } 回調(diào)取得兩個(gè)參數(shù)的作用: code:表示授權(quán)碼,必選項(xiàng)乍恐。該碼的有效期應(yīng)該很短,通常設(shè)為10分鐘茵烈,客戶端只能使用該碼一次百匆,否則會(huì)被授權(quán)服務(wù)器拒絕呜投。該碼與客戶端ID和重定向URI加匈,是一一對(duì)應(yīng)關(guān)系仑荐。 state:如果客戶端的請(qǐng)求中包含這個(gè)參數(shù)雕拼,認(rèn)證服務(wù)器的回應(yīng)也必須一模一樣包含這個(gè)參數(shù)粘招。 getToken:function(){ this.$token.getTokenFromService(this,this.code,(response)=>{ this.$token.savetoken(response.data); this.$router.push('/user'); },function (error) { alert(error); }); }
文件地址:src/util/token.js getTokenFromService:function (vue,code,callback,error) { vue.$ajax.post(vue.$config.accessTokenUri,{ client_id:vue.$config.clientId, client_secret:vue.$config.client_secret, code:code, redirect_uri:vue.$config.redirect_uri, grant_type:vue.$config.grant_type },{ headers:{"Accept":"application/json"} }) .then(callback) .catch(error); } 相關(guān)幾個(gè)參數(shù)的含義: grant_type:表示使用的授權(quán)模式,必選項(xiàng)洒扎,此處的值固定為"authorization_code"。 code:表示上一步獲得的授權(quán)碼袍冷,必選項(xiàng)磷醋。 redirect_uri:表示重定向URI胡诗,必選項(xiàng)邓线,且必須與A步驟中的該參數(shù)值保持一致煌恢。 client_id:表示客戶端ID,必選項(xiàng)瑰抵。
這里獲取了Access_Token作為身份憑證你雌,需要我們保存起來(lái)谍憔,可以保存在cookie中匪蝙,也可以選擇其他方式,在后續(xù)訪問資源服務(wù)器調(diào)用資源的時(shí)候需要攜帶Access_Token訪問逛球。
跨域問題
在獲取Access_Token時(shí)我們將會(huì)遇到跨域的問題千元,這里我才用的解決方案是利用proxyTable設(shè)置代理,用于解決我們開發(fā)環(huán)境中跨域問題颤绕,而生產(chǎn)環(huán)境可以選擇nginx等。這里就說一下proxyTable的做法
在config/index.js中的dev添加下面配置
dev:{
proxyTable: {
'/github':{
target:'https://github.com',
changeOrigin:true,
pathRewrite:{
'^/github':'/'
}
}
}
將src/config/config.js文件中的需要跨域的地址
accessTokenUri : "https://github.com/login/oauth/access_token"
改為
accessTokenUri : "/github/login/oauth/access_token"
3. 獲取身份信息
獲取用戶的身份信息是將認(rèn)證服務(wù)器作為資源服務(wù)器看待奥务,攜帶身份憑證Access_Token請(qǐng)求資源物独,資源服務(wù)器將通過認(rèn)證服務(wù)器檢測(cè)身份憑證的有效性作出相應(yīng)回復(fù)氯葬。對(duì)于前段我們的做法如下:
getUserInfo:function () {
var tokenInfo = this.$token.loadToken();
this.$ajax({
url:this.$config.userInfoUri+"?"+"access_token="+tokenInfo.access_token,
headers:{"Accept":"application/json"}
})
.then((response) =>{
this.user = response.data;
console.log(this.user);
})
.catch((error) =>{
this.$root.push("/logout")
});
}
4. 注銷
通過清除cookie或其他存儲(chǔ)方式實(shí)現(xiàn),這里就不貼代碼了帚称。
項(xiàng)目地址:https://github.com/izekers/OAuthDemo_vue