oauth身份验证方式_使用OAuth和Passport管理身份验证
oauth身份驗證方式
用戶組列表和信息(UGLI)應用程序開始很好地成形。 現在,您可以通過在“ 具有響應式Web設計的MEAN和UGLI CRUD ”中設置的CRUD屏幕顯示您創建的本地內容。 您還可以使用在“ MEAN遇見Meetup.com和微數據 ”中開發的服務來合并來自外部站點的內容。
與公眾共享會議信息是該項目的重要組成部分。 但是,作為用戶組組長,我也希望將某些活動限制為該組的注冊成員。 例如,通過關閉匿名訪問并要求登錄,我可能會選擇在評論我們的演示文稿時保留一些禮貌。 因此,在本期中,您將使用Meetup.com的OAuth服務為UGLI應用提供登錄功能。 請參閱下載以獲取示例代碼。
創建一個新的用戶帳號
通過單擊Sign up按鈕(如圖1所示),您的應用程序用戶可以創建一個新帳戶,該帳戶存儲在本地MongoDB中。 此功能內置于您的應用中-無需其他編程。
圖1. UGLI注冊頁面
關于本系列
MEAN(MongoDB,Express,AngularJS,Node.js)堆棧是長期流行的LAMP堆棧的現代挑戰者,用于使用開源軟件構建專業網站。 MEAN代表了體系結構和思維模型的重大轉變-從關系數據庫到NoSQL,從服務器端的Model-View-Controller到客戶端的單頁應用程序。 在本系列中,將學習MEAN堆棧的技術如何相互補充,以及如何使用該堆棧來創建二十一世紀的現代全堆棧JavaScript Web應用程序。
從開發的角度來看,這種默認行為無疑是最簡單的解決方案,但是就用戶體驗而言,它仍有一些不足之處。 您的用戶組成員已經在Meetup.com上擁有一個帳戶,用于RSVP即將舉行的會議。 要求他們創建和維護一組重復的憑據不僅煩人,而且公然違反了“不要自己重復”(DRY)原則。
認證與授權
每當您登錄網站時,都會發生兩處完全不同但相關的事情:
- 通過提供用戶名和密碼(或指紋,或視網膜掃描,或...),您就可以對自己進行身份驗證 -通過共享秘密密碼短語或唯一標識符來證明您的身份。 未經身份驗證,任何人都可以登錄到您的銀行網站并取款或登錄到您的社交媒體帳戶,然后開始以您的名義發表煽動性聲明。
- 通過身份驗證后,系統會找出您有權執行的操作。 您的銀行網站授權您從帳戶中進行存款和取款,但很可能不允許您調整利率或沖銷銀行費用。 要執行這些操作,您必須聯系客戶服務代表,該客戶的帳戶有權執行管理任務。
幸運的是,通過使用的MEAN堆棧,您可以設置使用OAuth和Passport的分布式身份驗證和授權解決方案。 簡單來說,您的用戶可以使用用于登錄Meetup.com的相同憑據登錄(認證)到UGLI應用程序。 但是,如果沒有用戶的許可,這是無法完成的。 他們必須允許(授權)UGLI應用使用其Meetup.com憑據。
即使通過OAuth對UGLI應用進行了授權,用戶憑據也不會與授權的應用共享。 您不會在UGLI中本地存儲一組重復的用戶名和密碼。 希望獲得授權的應用程序(UGLI)將用戶重定向到OAuth提供程序(Meetup.com),他們在其中提供其憑據(用戶名和密碼)。 用戶成功認證后,訪問令牌將返回給授權的應用程序。
這種方案減少了應用程序中的大量代碼和邏輯。 您不再需要擔心在服務器上存儲加密密碼-這是OAuth提供程序要解決的問題。 同樣,您不再必須編寫算法來強制使用強密碼或處理忘記的密碼或強制用戶定期更改其密碼。
因此,OAuth為您的用戶提供了更少的密碼來記憶,并且為您提供了更少的編寫代碼。 如果這不是雙贏方案的教科書定義,我不知道這是什么。
介紹OAuth和Passport
“您不再需要編寫算法來強制使用強密碼,也不必處理忘記的密碼,也不必強制用戶定期更改密碼。 ”
OAuth是用于分布式身份驗證和授權的開放標準。 它由Twitter和業務合作伙伴Ma.gnolia于2006年開發,旨在促進創建桌面小部件,這些小部件顯示來自已驗證服務的信息。 從那時起,OAuth被數百個主要網站采用,從Google到Facebook再到Twitter,GitHub,LinkedIn等。 (請參閱著名的OAuth服務提供商列表 。)
Passport是為Node.js編寫的OAuth庫。 具體來說,它是旨在與Express應用程序無縫集成的中間件。 有140多個Passport插件(稱為策略 )可供使用,這些插件是為每個OAuth提供程序量身定制的。
如果您在文本編輯器中打開UGLI應用程序的package.json文件(如清單1所示),則可以看到針對四種主要服務(Facebook,Twitter,LinkedIn和Google)的Passport策略,以及用于直接存儲憑據的本地策略。在MongoDB中。
清單1. package.json中的護照策略
"dependencies": {"passport": "~0.2.0","passport-local": "~1.0.0","passport-facebook": "~1.0.2","passport-twitter": "~1.0.2","passport-linkedin": "~0.1.3","passport-google-oauth": "~0.1.5" }使用現有示例作為指南,您將添加第六種策略,以將Meetup.com納入UGLI的OAuth提供程序。
安裝Meetup.com Passport策略
學到更多。 開發更多。 連接更多。
新的developerWorks Premium會員計劃通過Safari圖書在線提供對強大的開發工具和資源的無障礙訪問,其中包括500個頂級技術標題(數十個專門用于Web開發人員),主要開發人員活動的超低折扣,最近O'Reilly的視頻重播會議等。 立即注冊 。
如果您訪問使用Meetup API進行身份驗證 ,您將看到Meetup.com提供OAuth服務。 在網上快速搜索meetup.com passport.js strategy生成指向您正在尋找的庫的鏈接: passport-meetup 。
輸入npm install passport-meetup --save meetup npm install passport-meetup --save將庫下載到node_modules并更新package.json中的依賴項塊。
那是容易的部分。 制定好策略后,下一步就是將其合并到注冊和登錄頁面中。
將Meetup.com鏈接添加到注冊和登錄頁面
在文本編輯器中打開public / modules / users / views / signup.client.view.html。 在文件的頂部,您可以看到指向各種OAuth提供程序的鏈接(如清單2所示)。
清單2. public / modules / users / views / signup.client.view.html
<h3 class="col-md-12 text-center">Sign up using your social accounts</h3> <div class="col-md-12 text-center"><a href="/auth/facebook" class="undecorated-link"><img src="/modules/users/img/buttons/facebook.png"></a><a href="/auth/twitter" class="undecorated-link"><img src="/modules/users/img/buttons/twitter.png"></a><a href="/auth/google" class="undecorated-link"><img src="/modules/users/img/buttons/google.png"></a><a href="/auth/linkedin" class="undecorated-link"><img src="/modules/users/img/buttons/linkedin.png"></a> </div>將現有鏈接替換為指向您尚未創建的/ auth / meetup路由的鏈接,并顯示尚未下載的Meetup.com圖標(如清單3所示)。
清單3.鏈接到auth / meetup
<h3 class="col-md-12 text-center">Sign up using your Meetup.com account</h3> <div class="col-md-12 text-center"><a href="/auth/meetup" class="undecorated-link"><img src="/modules/users/img/buttons/meetup.png"></a> </div>訪問“ Meetup圖標”頁面,并將128x128像素的圖像保存到存儲其他社交媒體圖標的public / modules / users / img / buttons /。
現在已經禁用了注冊頁面,請在文本編輯器中打開public / modules / users / views / signin.client.view.html,并以與注冊頁面相同的方式對其進行調整(如清單1所示)。 4)。
清單4. public / modules / users / views / signin.client.view.html
<h3 class="col-md-12 text-center">Sign in using your Meetup.com account</h3> <div class="col-md-12 text-center"><a href="/auth/meetup" class="undecorated-link"><img src="/modules/users/img/buttons/meetup.png"></a></div>如果一切都按計劃進行,那么新的注冊頁面將如圖2所示。當然,如果沒有適當的路線,則單擊鏈接將出現404頁面未找到錯誤。 接下來,您將解決此問題。
圖2.新的UGLI注冊頁面
設置服務器端的身份驗證/會議路由
下一步是創建服務器端的auth / meetup路由。 回想一下,所有服務器端邏輯都存儲在app目錄中; 客戶端邏輯存儲在公用文件夾中。
在文本編輯器中打開app / routes / users.server.routes.js。 找到Facebook的代碼塊并復制/粘貼,然后用meetup替換facebook (如清單5所示)。
清單5. app / routes / users.server.routes.js
// Setting the facebook oauth routes app.route('/auth/facebook').get(passport.authenticate('facebook', {scope: ['email'] })); app.route('/auth/facebook/callback').get(users.oauthCallback('facebook'));// Setting the meetup oauth routes app.route('/auth/meetup').get(passport.authenticate('meetup', {scope: ['email'] })); app.route('/auth/meetup/callback').get(users.oauthCallback('meetup'));還記得上一節中在注冊和登錄頁面上創建的指向auth / meupup的超鏈接嗎? 當用戶通過單擊鏈接向服務器發送HTTP GET請求時,將觸發第一條路由(auth / meetup)。 Passport將嘗試通過使用passport-meetup策略來驗證用戶身份。 登錄嘗試的結果(成功或否則)將異步發送到第二個auth / meetup / callback路由。
如果現在單擊注冊頁面上的“會議集會”鏈接,則會收到500服務器錯誤而不是404錯誤。這不完全是一種改進,但至少是一種進步。 下一步:配置聚會策略。
配置聚會策略
您可以在同名的config / strategies目錄中找到所有Passport策略。 將facebook.js復制到meetup.js,然后在文本編輯器中打開meetup.js。
與上一節中的操作一樣,您將遍歷此文件并將所有facebook實例替換為meetup 。 但這不僅僅是簡單的查找/替換操作。 您還需要進行一些小的配置更改。
首先,將文件頂部所需的庫從Facebook策略更改為Meetup策略(如清單6所示)。
清單6. config / strategies / meetup.js
/*** Module dependencies.*/ var passport = require('passport'),url = require('url'),MeetupStrategy = require('passport-meetup').Strategy,config = require('../config'),users = require('../../app/controllers/users');接下來,您需要自定義傳遞給新策略的選項塊。 這些價值因策略而異。 清單7顯示了Facebook策略選項,這些選項不適用于Meetup。
清單7.不適用于Meetup的Facebook選項
module.exports = function() {// Use facebook strategypassport.use(new FacebookStrategy({clientID: config.facebook.clientID,clientSecret: config.facebook.clientSecret,callbackURL: config.facebook.callbackURL,passReqToCallback: true},值得慶幸的是,您npm install passport-meetup模塊附帶了示例代碼。 在文本編輯器中打開node_modules / passport-meetup / examples / login / app.js。 查找passport.use function call (如清單8所示)。
清單8. node_modules / passport-meetup / examples / login / app.js
passport.use(new MeetupStrategy({consumerKey: MEETUP_KEY,consumerSecret: MEETUP_SECRET,callbackURL: "http://127.0.0.1:3000/auth/meetup/callback"},將此代碼段復制到metup.js,覆蓋Facebook代碼。 接下來,將冒號右側的值更改為清單9中所示的值。
清單9.會用的Meetup選項
passport.use(new MeetupStrategy({consumerKey: config.meetup.consumerKey,consumerSecret: config.meetup.consumerSecret,callbackURL: config.meetup.callbackURL,},OAuth訪問令牌和刷新令牌
訪問令牌就像電影票:您從票房獲得的一紙小紙鈔,證明您是為入場費付費的人。 當您進入劇院時,您將閑聊交給一位員工,該員工告訴您您有權觀看哪部電影,并且該員工將閑聊撕成兩半以確保僅使用一次。
同樣,OAuth訪問令牌是具有短生存時間(TTL)的一次性令牌。 下次用戶通過Meetup鏈接登錄UGLI時,他或她不需要提供用戶名和密碼。 而是,Passport將刷新令牌發送到Meetup。 除非用戶從Meetup撤消了對UGLI的訪問權限,否則Meetup會以短TTL的新訪問令牌響應。
刷新令牌應該在您的系統中保留很長時間-本質上,只要存在用戶帳戶,就可以保留。 相比之下,訪問令牌是短暫的瞬態對象,每次用戶向遠程OAuth提供程序進行身份驗證時都會重新生成。
在下一部分中,您將從Meetup.com獲取consumerKey和consumerSecret ,并將它們保存在config.js文件中。 但是,您需要先對當前文件進行一些其他更改,然后再進行操作。
緊隨new MeetupStrategy構造函數之后的函數是事件處理程序,該事件處理程序從Meetup.com接收響應。 您對響應的三個關鍵部分感興趣:訪問令牌,刷新令牌和用戶配置文件。 (有關令牌的詳細信息,請參見OAuth訪問令牌和刷新令牌側欄。)
訪問令牌和刷新令牌是您不變地傳遞給Passport的字符串。 盡管它們對于OAuth操作的成功至關重要,但他們很無聊。 (清單10包含了兩者的示例。)
用戶個人資料更有趣。 這是OAuth提供程序返回的JSON對象,其中包含有關成功通過身份驗證的用戶的信息。 具體細節因OAuth提供者而異。 清單10顯示了Meetup返回的用戶個人資料的示例。
清單10.從Meetup.com OAuth提供者返回的用戶個人資料
{ provider: 'meetup',id: 13848777,displayName: 'Scott Davis',_raw: '{ "results": [{"status": "active","link": "http:\\\/\\\/www.meetup.com\\\/members\\\/13848777","photo": {"photo_link": "http:\\\/\\\/photos1.meetupstatic.com\\\/photos\\\/member\\\/7\\\/4\\\/d\\\/2\\ \/member_11849906.jpeg","thumb_link": "http:\\\/\\\/photos3.meetupstatic.com\\\/photos\\\/member\\\/7\\\/4\\\/d\\\/2\\ \/thumb_11849906.jpeg","photo_id": 11849906},"country": "us","state": "CO", "city": "Denver","id": 13848777,"joined": 1295844957000,"bio": "Scott Davis is the founder of ThirstyHead.com, a training and consulting company that specializes in leading-edge technology solutions like HTML 5, NoSQL, Groovy, and Grails.","name": "Scott Davis","other_services": {"twitter": {"identifier": "@scottdavis99"}}}] }',_json: { results: [ [Object] ],meta: { link: 'https://api.meetup.com/2/members',total_count: 1,url: 'https://api.meetup.com/2/members?order=name&member_id=13848777&offset=0 &format=json&page=800',title: 'Meetup Members v2',updated: 1392763702000,description: 'API method for accessing members of Meetup Groups',method: 'Members',},accessToken: 'c7b5577bb80aab55439785cd86abcdef',refreshToken: '2af98db68950235a1e2519a734abcdef' } }如您所見,Meetup返回用戶詳細信息,例如姓名,居住地,加入日期,個人資料照片,鏈接的社交媒體帳戶等。
完成Meetup策略的自定義操作的最后一件事是將Meetup配置文件字段映射回app / models / user.server.model.js中定義的User Mongoose對象。 在config / strategies / meetup.js中編輯其余的Facebook塊,如清單11所示。
清單11.將OAuth用戶配置文件映射到User對象
// Create the user OAuth profile var providerUserProfile = {firstName: '',lastName: '',displayName: profile.displayName,email: '',username: profile.id,provider: profile.provider,providerIdentifierField: 'id',providerData: providerData };如果您在Meetup配置文件JSON中看到要添加到User對象的字段,那么這是進行更改的最佳時機。 不要忘記在public / modules / users / views中將新字段添加到HTML表單中。
完成的config / strategies / meetup.js應該類似于清單12。
清單12.完整的config / strategies / meetup.js
'use strict';/*** Module dependencies.*/ var passport = require('passport'),url = require('url'),MeetupStrategy = require('passport-meetup').Strategy,config = require('../config'),users = require('../../app/controllers/users');module.exports = function() {// Use meetup strategypassport.use(new MeetupStrategy({consumerKey: config.meetup.clientID,consumerSecret: config.meetup.clientSecret,callbackURL: config.meetup.callbackURL,},function(req, accessToken, refreshToken, profile, done) {// Set the provider data and include tokensvar providerData = profile._json;providerData.accessToken = accessToken;providerData.refreshToken = refreshToken;// Create the user OAuth profilevar providerUserProfile = {firstName: '',lastName: '',displayName: profile.displayName,email: '',username: profile.id,provider: profile.provider,providerIdentifierField: 'id',providerData: providerData};// Save the user OAuth profileusers.saveOAuthUserProfile(req, providerUserProfile, done);})); };在測試此代碼之前,您還需要做一件事:從Meetup獲取consumerKey和consumerSecret 。
獲取Meetup的consumerKey和consumerSecret
到目前為止,我已經用了整整篇文章來討論對用戶進行身份驗證。 但是,在用戶可以使用OAuth登錄UGLI之前,您(開發人員)必須提供證明您的組織符合要求的證據。 您可以通過向用戶提供公鑰( consumerKey )來實現。 您的應用程序還需要知道其私鑰( consumerSecret )是什么。
如果您以前曾使用過公鑰基礎結構 (PKI),那么您將知道隱藏私鑰并確保其安全至關重要。 如果其他人發現了您的私鑰,他們可以偽裝成您的組織。 相反,如果您不與用戶共享您的公鑰,那么他們將無法證明您是誰。
如果您是Meetup.com上用戶組的組織者,則可以從Meetup的“ 您的OAuth消費者”頁面中生成consumerKey和consumerSecret (請參見圖3)。 我將HTML5 Denver User Group用作消費者名稱,將http://www.meetup.com/HTML5-Denver-Users-Group/用于應用程序網站,并將http://localhost:3000/auth/meetup/callback用于重定向URI。 將UGLI應用程序投入生產后,我將把應用程序網站更改為http://html5denver.com ,并將重定向URI更改為http://html5denver.com/auth/meetup/callback 。
圖3.生成HTML5 Denver的consumerKey和consumerSecret
如果您沒有在Meetup.com上運行用戶組,則您的帳戶無權代表該組生成OAuth密鑰。 但是,您仍然可以為其他社交媒體帳戶之一生成令牌,并相應地調整本文中的步驟。 請參閱實施通過Twitter登錄以為您的Twitter帳戶生成應用程序密鑰,或訪問訪問令牌以使用您的Facebook帳戶。 在your social media website oauth keys上進行快速網絡搜索應該會得到逐步說明。
將組織OAuth密鑰添加到您的應用程序
獲得兩個密鑰(公共密鑰和私有密鑰)之后,您將通過環境變量將它們添加到您的應用程序中-就像在“ 瀏覽MEAN應用程序 ”中更改PORT 。
回想一下,您可以設置變量,這些變量根據您所運行的模式( development , production或test 。 特定于環境的值存儲在config / env中。 在文本編輯器中打開config / env / development.js。 復制/粘貼Facebook塊,并針對Meetup進行相應調整(如清單13所示)。 可以肯定的屬性名稱匹配這里您在使用的屬性名稱passport.use在配置/策略/ meetup.js函數調用。
清單13. config / env / development.js
'use strict';module.exports = {db: 'mongodb://localhost/test-dev',app: {title: 'HTML5 Denver'},meetup: {consumerKey: process.env.MEETUP_KEY || 'APP_ID',consumerSecret: process.env.MEETUP_SECRET || 'APP_SECRET',callbackURL: 'http://localhost:3000/auth/meetup/callback'}, facebook: {clientID: process.env.FACEBOOK_ID || 'APP_ID',clientSecret: process.env.FACEBOOK_SECRET || 'APP_SECRET',callbackURL: 'http://localhost:3000/auth/facebook/callback'},twitter: {clientID: process.env.TWITTER_KEY || 'CONSUMER_KEY',clientSecret: process.env.TWITTER_SECRET || 'CONSUMER_SECRET',callbackURL: 'http://localhost:3000/auth/twitter/callback'},google: {clientID: process.env.GOOGLE_ID || 'APP_ID',clientSecret: process.env.GOOGLE_SECRET || 'APP_SECRET',callbackURL: 'http://localhost:3000/auth/google/callback'},linkedin: {clientID: process.env.LINKEDIN_ID || 'APP_ID',clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',callbackURL: 'http://localhost:3000/auth/linkedin/callback'} };您可以使用上一部分中檢索到的consumerKey和consumerSecret硬編碼值替換APP_ID和APP_SECRET 。 但是更安全的解決方案是通過環境變量將這些值提供給UGLI應用程序。 要使用組織的consumerKey和consumerSecret啟動應用程序,請輸入:
MEETUP_KEY=l75fkklhurkack36eelfhhfhjc MEETUP_SECRET=abcdeg316jd3ni43f21u1abcde NODE_ENV=development grunt上線之前,請不要忘記對config / env / production.js進行類似的調整。 而且,如果您之前創建了用戶帳戶,請確保將其從MongoDB的html5-denver-dev數據庫中刪除,以便您可以重新完成新帳戶的創建過程。
結論
Perl編程語言的創建者拉里·沃爾(Larry Wall)曾有句著名的話:“簡單的事情應該很容易,而困難的事情應該可以?!?我希望這一觀點能很好地總結您將OAuth和Passport連接起來以使用Meetup.com滿足您的分布式身份驗證和授權需求的經驗。
在下一期Mastering MEAN文章中 ,我將帶您了解MEAN堆棧中內置的測試基礎結構。 您將了解用于服務器端測試的Mocha,用于客戶端測試的Jasmine以及用于在多個瀏覽器上運行測試的Karma。 在此之前,請盡情掌握MEAN。
翻譯自: https://www.ibm.com/developerworks/opensource/library/wa-mean5/index.html
oauth身份驗證方式
總結
以上是生活随笔為你收集整理的oauth身份验证方式_使用OAuth和Passport管理身份验证的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 任天堂公司:超级玛丽的诞生
- 下一篇: chrome 该文件可能已遭到删除、移动