一妨马、概念及場景
Oauth2.0(Open Authorization)協(xié)議是一個關(guān)于授權(quán)(authorization)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn)挺举,是目前應(yīng)用最廣泛的標(biāo)準(zhǔn)之一杀赢。簡單講,所謂授權(quán)指的是我們通過微信湘纵、github等帳號的方式登錄比如V2EX脂崔、知乎、簡書這樣的網(wǎng)站或應(yīng)用梧喷。目前包括github砌左、facebook、twitter铺敌、微信汇歹、微博、QQ等社交工具都集成了Oauth2.0協(xié)議以供第三方應(yīng)用程序使用偿凭,實現(xiàn)一個社交帳號打通所有應(yīng)用产弹。
停下來想一想,刷朋友圈的時候是不是經(jīng)常遇到這樣的情況呢( ̄▽ ̄)弯囊,下面我將結(jié)合自己的開發(fā)和校招經(jīng)歷痰哨,分享一下在Oauth2.0的授權(quán)碼模式下進(jìn)行第三方應(yīng)用程序開發(fā)的過程。
二常挚、授權(quán)的角色
1作谭、Third-party application:第三方應(yīng)用程序,即上面提到的V2EX奄毡、知乎折欠、簡書
2、Resource Owner:資源所有者吼过,也就是持有微信锐秦、github帳號的用戶。
3盗忱、User Agent:用戶代理酱床,比如瀏覽器這樣的工具。
4趟佃、Authorization server:認(rèn)證服務(wù)器扇谣,也就是微信、github配置的專門用來處理認(rèn)證的服務(wù)器闲昭。
5罐寨、Resource server:資源服務(wù)器,即微信序矩、github存放用戶生成的資源如帳號鸯绿、頭像、昵稱等的服務(wù)器。需要注意的是它與認(rèn)證服務(wù)器瓶蝴,可以是同一臺服務(wù)器毒返,也可以是不同的服務(wù)器
三、授權(quán)的模式
客戶端必須得到用戶的授權(quán)(authorization grant)拧簸,才能獲得用戶獲取資源比如微信頭像、昵稱等的令牌(access token)聚霜。OAuth 2.0定義了四種授權(quán)方式狡恬。
1、授權(quán)碼模式(authorization code)
2蝎宇、簡化模式(implicit)
3弟劲、密碼模式(resource owner password credentials)
4、客戶端模式(client credentials)
其中姥芥,授權(quán)碼模式(authorization code)是功能最完整兔乞、流程最嚴(yán)密的授權(quán)模式。
四凉唐、授權(quán)碼(Authorization Code)模式
在開發(fā)準(zhǔn)備階段庸追,需要從服務(wù)提供商開發(fā)者平臺(以金數(shù)據(jù)為例)注冊,取得用以獲得授權(quán)碼(code)的授權(quán)域(授權(quán)的網(wǎng)址)台囱、應(yīng)用ID(client_id)和對應(yīng)密鑰(client_secret)淡溯,并配置我們要開發(fā)的第三方應(yīng)用的回調(diào)地址(redirect_uri)、授權(quán)范圍(scope)簿训;這就相當(dāng)于校招的時候網(wǎng)申咱娶、考核的過程。
當(dāng)我們畢業(yè)參加招聘時一般會經(jīng)歷下面幾個過程:
報名?---->參加筆試面試---->公司發(fā)放offer---->拿到offer后進(jìn)入公司拿到工牌---->有了工牌就可以使用公司的資源
其實整個Oauth2.0的授權(quán)碼模式和這個很相似强品。
(1)流程示意圖:
(2)完整的過程:
第一步膘侮,帶上這些參數(shù)向認(rèn)證服務(wù)器(Authorization server)發(fā)送授權(quán)請求,認(rèn)證服務(wù)器收到請求的榛,驗證參數(shù)琼了,若成功,彈出登錄頁面或授權(quán)頁面(比如上圖的截圖)夫晌,若參數(shù)不一致雕薪,彈出錯誤。這一步好比校招的時候參加面試(??ω??)
*請求參數(shù)包括應(yīng)用ID(client_id)晓淀、回調(diào)地址(redirect_uri)蹦哼、授權(quán)范圍(scope)、response_type(Oauth2.0為code)要糊、狀態(tài)(state)等
第二步,資源所有者(用戶)確認(rèn)授權(quán),認(rèn)證服務(wù)器攜帶授權(quán)碼(code)和狀態(tài)參數(shù)(state)返回請求到相應(yīng)的回調(diào)地址(redirect_uri)锄俄。可以類比校招的時候參公司給你發(fā)了offer (°?°)?
第三步局劲,拿到了offer后,哦不奶赠,拿到了授權(quán)碼(code)鱼填,就可以向認(rèn)證服務(wù)器請求令牌(access token),認(rèn)證服務(wù)器會返回生成的令牌(access token)及刷新令牌時用到的(refresh token)等參數(shù)毅戈。發(fā)工牌啦 ("▔□▔)/
*請求參數(shù)包括應(yīng)用ID(client_id)苹丸、對應(yīng)密鑰(client_secret)、苇经、上一步獲得的授權(quán)碼(code)赘理、回調(diào)地址(redirect_uri)、授權(quán)模式(grant_type扇单,這里是authorization_code)商模、授權(quán)范圍(scope)、上一步獲得的狀態(tài)(state)等
第四步蜘澜,用戶代理(瀏覽器)攜帶令牌(access token)向資源服務(wù)器發(fā)送請求施流,訪問在第三方應(yīng)用程序授權(quán)范圍(scope)內(nèi)的資源,比如微信名稱鄙信、頭像等瞪醋。拿到了工牌之后可以享受公司的資源 (⌒▽⌒)
五、那些坑
1装诡、回調(diào)地址必須一致银受;
有時候我們在測試服務(wù)器時授權(quán)是正常的,在產(chǎn)品服務(wù)器上就不行慎王,因為回調(diào)地址是唯一的蚓土,且嚴(yán)格一致的。
2赖淤、refresh token的過期時間問題蜀漆;
因為每個令牌(access token)都是有過期時間(expires_in)的,一般默認(rèn)為7200s咱旱,也就是2h确丢,令牌過期后如果進(jìn)行訪問資源,服務(wù)器會返回403(未授權(quán))錯誤吐限,所以令牌必須即時提前刷新鲜侥。
為了避免重新獲得令牌的過程剛開始一樣復(fù)雜,Oauth2.0規(guī)定每個令牌(access token)生成時必須同時生成過期時間(expires_in)和刷新令牌(refresh token)诸典,在任意時間描函,使用刷新令牌(refresh token)可以向認(rèn)證服務(wù)器請求生成一個新的令牌(access token),此時原有的令牌和刷新令牌失效!所以如果你的本地環(huán)境和測試服務(wù)器使用的是同一個令牌時舀寓,當(dāng)本地環(huán)境提前刷新token后胆数,將造成你的測試服務(wù)器無法繼續(xù)刷新token;
刷新token的2種方式:
1互墓、主動式:提前存好令牌(access token)的過期時間(令牌過期時間=獲得accesstoken的時間+過期時間(expires_in)- 冗余時間t)必尼。在服務(wù)器運行crontab定時任務(wù), 每隔小于t的時間篡撵,檢查數(shù)據(jù)庫中所有用戶token的令牌過期時間是否大于當(dāng)前時間判莉,自動刷新;這樣的好處是保證每時每刻token都是有效的育谬,但是對于服務(wù)器有一定負(fù)載券盅;
2、被動式:(令牌過期時間=獲得access token的時間+過期時間(expires_in)斑司。當(dāng)要使用當(dāng)前令牌(access token)時渗饮,檢查該令牌過期時間是否大于當(dāng)前時間,進(jìn)行刷新宿刮;這是最簡單的做法互站,能夠節(jié)省資源,但是有一定幾率會造成用戶體驗過慢僵缺,畢竟刷新token需要時間胡桃;不推薦被動式刷新。
以上是我在進(jìn)行金數(shù)據(jù)應(yīng)用中心的抽獎應(yīng)用的開發(fā)過程中的一些體會磕潮,當(dāng)然翠胰,目前基本上所有的框架都封裝了Oauth2.0的庫,大家只需要按照文檔使用這些庫自脯,如果大家是Rails愛好者之景,給大家推薦一下Omniauth,如果大家是PHP Laravel的開發(fā)者膏潮,給大家推薦一下Laravel Socialite這個庫锻狗,當(dāng)然,像金數(shù)據(jù)這樣的純api有很多復(fù)雜的請求焕参,大家可以參考我做的集成SocialiteForJinshuju轻纪。
歡迎大家能分享更多的內(nèi)容,嗶哩嗶哩 - ( ゜- ゜)つロ 乾杯~?
參考: