使用Mozilla Persona认证用户的指南
到目前為止,只有Twitter和Facebook身份驗(yàn)證,我決定將Mozilla Persona添加到我最新項(xiàng)目( 計(jì)算機(jī) ,計(jì)算機(jī)生成的音樂(lè))的列表中。 為什么?
- 我喜歡嘗試新事物
- 存儲(chǔ)密碼是一個(gè)艱巨的過(guò)程,盡管我知道該怎么做,甚至大部分代碼都寫在另一個(gè)項(xiàng)目中,但我認(rèn)為我不應(yīng)該為每個(gè)需要密碼認(rèn)證的站點(diǎn)做出貢獻(xiàn)
- Mozilla是一個(gè)開放的基金會(huì),迄今為止已經(jīng)產(chǎn)生了許多出色的產(chǎn)品。 Persona實(shí)現(xiàn)了BrowserID協(xié)議,將來(lái)可能會(huì)在Firefox以外的其他瀏覽器中本地支持(目前,您需要包含.js文件)
- 第三方身份驗(yàn)證已經(jīng)嘗試了很多次,這是一件很了不起的事情,但是由于一些原因,它并不是主流。 有所不同,《女神異聞錄》可能會(huì)成功地變得更受歡迎。
- Mozilla的解釋很有意義
因此,我從“快速設(shè)置”指南開始。 看起來(lái)真的很容易。 比OpenID或OAuth身份驗(yàn)證容易得多–您無(wú)需在任何地方注冊(cè)任何內(nèi)容,不需要第三方庫(kù)來(lái)在服務(wù)器上處理驗(yàn)證,并且您無(wú)需學(xué)習(xí)復(fù)雜的身份驗(yàn)證流程,因?yàn)樵摿鞒毯芎?jiǎn)單:
當(dāng)然,它不是那么簡(jiǎn)單,但是有一些需要注意的地方在本教程中沒(méi)有提到。 因此,讓我們一步一步地遵循官方教程,并且我將在每一點(diǎn)上進(jìn)行擴(kuò)展(使用的服務(wù)器端語(yǔ)言是Java,但它很簡(jiǎn)單,您可以使用任何語(yǔ)言來(lái)完成)
1.包括.js文件-簡(jiǎn)單。 建議從Mozilla服務(wù)器獲取js文件,而不是將其存儲(chǔ)在本地,因?yàn)樗赡軙?huì)更改(例如,為了修復(fù)錯(cuò)誤)。 如果將js文件合并到一個(gè)文件中(為了更快地加載頁(yè)面)可能會(huì)比較棘手,但是可能您的機(jī)制允許加載遠(yuǎn)程js文件。
2.登錄和退出按鈕。 這看起來(lái)也很容易。 最好有條件地添加注銷處理程序–僅當(dāng)用戶已使用Persona登錄時(shí)(而不是您的站點(diǎn)支持的其他身份驗(yàn)證方法)
3.偵聽身份驗(yàn)證事件。 建議將偵聽事件放在所有頁(yè)面上(例如,包含在標(biāo)題模板中)。 但是這里有個(gè)問(wèn)題。 如果您的用戶已經(jīng)在Persona中進(jìn)行了身份驗(yàn)證,但是他的會(huì)話在您的站點(diǎn)上已過(guò)期,則腳本將自動(dòng)登錄該用戶。 這將需要在頁(yè)面加載后的幾秒鐘內(nèi)重新加載頁(yè)面。 這并不一定是您或用戶想要的-例如,在我的情況下,這可能意味著他們剛剛播放的曲目由于頁(yè)面刷新而中斷。 當(dāng)然可以使用AJAX來(lái)完成,但是當(dāng)UI中的某些內(nèi)容沒(méi)有明顯原因發(fā)生更改時(shí),肯定會(huì)造成混亂。 下面,我將顯示針對(duì)此問(wèn)題的修復(fù)程序。 另外,注銷偵聽器可能并不是到處都需要的-據(jù)我了解,萬(wàn)一您注銷了Persona,它將自動(dòng)注銷用戶。 這可能不是您想要的,例如,用戶可能希望保留一些打開的選項(xiàng)卡,其中某些文件在注銷時(shí)無(wú)法訪問(wèn)。
4.驗(yàn)證服務(wù)器上的斷言。 在這里,您可能需要第3方庫(kù)來(lái)調(diào)用驗(yàn)證端點(diǎn)并解析json結(jié)果,但是這些是您可能已經(jīng)包含的非常標(biāo)準(zhǔn)的庫(kù)。
現(xiàn)在,如何解決自動(dòng)身份驗(yàn)證的問(wèn)題? 聲明一個(gè)新變量userRequestedAuthentication ,該變量保存身份驗(yàn)證是由用戶顯式發(fā)起還是由用戶自動(dòng)發(fā)起。 在登錄按鈕中,單擊處理程序,將該變量設(shè)置為true 。 這是js代碼的樣子(順便說(shuō)一句,我認(rèn)為可以將代碼放在document.ready()中,而不是直接放在script標(biāo)記中。假設(shè)您以后需要在處理程序方法中使用一些DOM資源,頁(yè)面已完全加載。另一方面,這可能會(huì)減慢該過(guò)程的速度)。 請(qǐng)注意,您可以在所有頁(yè)面上包括一個(gè)空的onlogin處理程序,并且僅在身份驗(yàn)證頁(yè)面上具有完整的處理程序。 但是,鑒于登錄按鈕位于主頁(yè)上,或帶有javascript模態(tài)窗口,因此可以在任何地方/在多個(gè)頁(yè)面上都可以使用。
<script type='text/javascript'>var loggedInUser = ${context.user != null ? ''' + context.user.email + ''' : 'null'};var userRequestedAuthentication = false;navigator.id.watch({loggedInUser : loggedInUser,onlogin : function(assertion) {$.ajax({type : 'POST',url : '${root}/persona/auth',data : {assertion : assertion, userRequestedAuthentication : userRequestedAuthentication},success : function(data) {if (data != '') {window.location.href = '${root}' + data;}},error : function(xhr, status, err) {alert('Authentication failure: ' + err);}});},onlogout : function() {window.locaiton.open('${root}/logout');}}); </script>如您所見,參數(shù)被傳遞到服務(wù)器端代碼。 那里發(fā)生了什么?
@RequestMapping('/persona/auth') @ResponseBody public String authenticateWithPersona(@RequestParam String assertion,@RequestParam boolean userRequestedAuthentication, HttpServletRequest request, Model model)throws IOException {if (context.getUser() != null) {return '';}MultiValueMap<String, String> params = new LinkedMultiValueMap<>();params.add('assertion', assertion);params.add('audience', request.getScheme() + '://' + request.getServerName() + ':' + (request.getServerPort() == 80 ? '' : request.getServerPort()));PersonaVerificationResponse response = restTemplate.postForObject('https://verifier.login.persona.org/verify', params, PersonaVerificationResponse.class);if (response.getStatus().equals('okay')) {User user = userService.getUserByEmail(response.getEmail());if (user == null && userRequestedAuthentication) {return '/signup?email=' + response.getEmail();} else if (user != null){if (userRequestedAuthentication || user.isLoginAutomatically()) {context.setUser(user);return '/';} else {return '';}} else {return ''; //in case this is not a user-requested operation, do nothing}} else {logger.warn('Persona authentication failed due to reason: ' + response.getReason());throw new IllegalStateException('Authentication failed');} }邏輯看起來(lái)比您希望的更復(fù)雜,但是讓我解釋一下:
- 正如您在javascript代碼中看到的那樣,空字符串表示“不執(zhí)行任何操作”。 如果返回任何其他內(nèi)容,則javascript將打開該頁(yè)面。 如果不使用spring-mvc,則無(wú)需將其從方法中返回@ResponseBody字符串,而是將其寫入響應(yīng)輸出流中(或用php術(shù)語(yǔ)–將其回顯)。
- 首先,您檢查系統(tǒng)中是否已經(jīng)有經(jīng)過(guò)身份驗(yàn)證的用戶。 如果有,則什么也不做。 我不確定是否存在Persona在已通過(guò)身份驗(yàn)證的用戶上調(diào)用“ onlogin”的情況,但是如果您使用其他身份驗(yàn)證選項(xiàng),Persona不會(huì)知道您的用戶已經(jīng)使用Twitter登錄。
- 然后,您調(diào)用驗(yàn)證URL并將結(jié)果解析為JSON。 我已經(jīng)使用過(guò)RestTemplate ,但是任何東西都可以使用RestTemplate ,URLConnection。 對(duì)于JSON解析,spring在后臺(tái)使用了Jackson。 您只需要編寫一個(gè)值對(duì)象,即可保存Persona可能返回的所有屬性。 到目前為止,我只包括:狀態(tài),電子郵件和原因(杰克遜詳細(xì)信息:ignoreUnknown = true,spring-mvc詳細(xì)信息:您需要將FormHttpMessageConverter設(shè)置為RestTemplate )。 重要的是,“受眾”參數(shù)必須是用戶當(dāng)前所在的域。 無(wú)論是否使用www,它都會(huì)有所不同,因此請(qǐng)對(duì)其進(jìn)行重構(gòu),而不是對(duì)其進(jìn)行硬編碼或從屬性中加載它。 即使您從www重定向到no-www(反之亦然),您仍應(yīng)為測(cè)試而動(dòng)態(tài)獲取該URL –測(cè)試環(huán)境的URL與生產(chǎn)環(huán)境的URL不同。
- 如果Persona身份驗(yàn)證為“可以”,則您嘗試在數(shù)據(jù)庫(kù)中查找具有該電子郵件的用戶。
- 如果沒(méi)有這樣的用戶,并且已手動(dòng)觸發(fā)了身份驗(yàn)證操作,則將用戶發(fā)送到注冊(cè)頁(yè)面并提供電子郵件作為參數(shù)(您也可以在http會(huì)話中進(jìn)行設(shè)置,以使用戶無(wú)法對(duì)其進(jìn)行修改)。 然后,注冊(cè)頁(yè)面會(huì)詢問(wèn)其他詳細(xì)信息-名稱,用戶名,出生日期或您認(rèn)為合適的任何信息(但請(qǐng)盡量減少-最好僅是全名)。 如果僅需要電子郵件地址,而無(wú)需其他任何內(nèi)容,則可以跳過(guò)注冊(cè)頁(yè)面并強(qiáng)制注冊(cè)用戶。 注冊(cè)完成后,您登錄用戶。 請(qǐng)注意,如果您已將電子郵件存儲(chǔ)在會(huì)話中(即用戶無(wú)法從注冊(cè)頁(yè)面進(jìn)行修改),則可以跳過(guò)確認(rèn)電子郵件-Persona已確認(rèn)該電子郵件
- 如果您的數(shù)據(jù)庫(kù)中有一個(gè)使用該電子郵件的用戶,請(qǐng)檢查該用戶是否已請(qǐng)求該操作,或者是否已(通過(guò)注冊(cè)頁(yè)面中的復(fù)選框)指示他要自動(dòng)登錄。考慮–應(yīng)該詢問(wèn)用戶,還是應(yīng)該始終將其設(shè)置為true或false? 我已經(jīng)添加了復(fù)選框。 如果應(yīng)該登錄,則將用戶設(shè)置在會(huì)話中,然后重定向到home(或上一頁(yè),或“用戶home”的任何頁(yè)面)(“ context”是會(huì)話范圍的Bean。您可以將其替換為session.setAttribute('user', user) )。 如果身份驗(yàn)證嘗試是自動(dòng)的,但用戶不希望這樣做,則不執(zhí)行任何操作。 最后一個(gè)“其他”是針對(duì)用戶在您的站點(diǎn)上沒(méi)有帳戶并且觸發(fā)了自動(dòng)身份驗(yàn)證的情況–在這種情況下不執(zhí)行任何操作,否則最終將無(wú)休止地重定向到注冊(cè)頁(yè)面
- 如果驗(yàn)證失敗,請(qǐng)務(wù)必記錄原因-然后您可以通過(guò)查看日志來(lái)檢查一切是否正常
使用電子郵件作為唯一標(biāo)識(shí)符的一個(gè)很酷的副作用是(如果使數(shù)據(jù)庫(kù)列成為唯一 ),如果稍后將Persona添加到您的網(wǎng)站,即使用戶以其他方式注冊(cè)(例如,facebook或常規(guī)注冊(cè)),用戶也可以登錄。 因此,他們可以將密碼設(shè)置為長(zhǎng)而難以記住的密碼,并僅使用Persona繼續(xù)登錄。
我從實(shí)現(xiàn)中省略的細(xì)節(jié)很簡(jiǎn)單:注冊(cè)頁(yè)面只是收集字段并將其提交給/ completeRegistration處理程序,該處理程序?qū)⑿掠脩舸鎯?chǔ)在數(shù)據(jù)庫(kù)中。 / logout URL僅清除會(huì)話(如果存儲(chǔ)了cookie,則清除cookie)。 順便說(shuō)一句,如果啟用了自動(dòng)登錄,并且Persona是您唯一的身份驗(yàn)證方法,則可能不需要存儲(chǔ)cookie來(lái)保持會(huì)話過(guò)期后仍保持用戶登錄狀態(tài)。
總體而言,即使我提出了要點(diǎn),實(shí)現(xiàn)也仍然很簡(jiǎn)單。 女神異聞錄看起來(lái)很棒,我希望很快能在更多站點(diǎn)上看到它。
參考: Bozho的技術(shù)博客博客上的JCG合作伙伴 Bozhidar Bozhanov的 Mozilla Persona身份驗(yàn)證用戶指南 。
翻譯自: https://www.javacodegeeks.com/2012/12/a-guide-to-authenticating-users-with-mozilla-persona.html
總結(jié)
以上是生活随笔為你收集整理的使用Mozilla Persona认证用户的指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: wr886n路由器怎么设置wr886n路
- 下一篇: 打印机怎么连接电脑如何将打印机与电脑连接