Apache Wicket:記住我的功能

在Web應用程序中,具有“記住我”功能非常普遍,該功能使用戶每次訪問我們的網站時都能自動登錄。

可以使用Spring Security來實現這種功能,但我認為將基于請求的身份驗證框架與基于組件的Web框架結合使用并不是最好的主意。 這兩個世界不能很好地融合在一起,所以我更喜歡使用我自己的烘焙解決方案,我將在下面介紹。

基礎項目

我們從一個簡單的Web應用程序開始,該應用程序使用最新的仍很熱門的Apache Wicket 6編寫。 您可以從GitHub下載完整的源代碼,并使用mvn clean compile jetty:run啟動應用程序。

基本應用程序包含兩個頁面:

  • 主頁:顯示已登錄和未登錄用戶的歡迎消息,或者注銷或登錄鏈接。
  • 登錄頁面:允許用戶基于簡單的用戶內存集合進行登錄。 一些有效的登錄名/密碼對:John / john,Lisa / lisa,Tom / tom。

記住我的功能

實現“記住我”功能的標準方法如下:

  1. 詢問用戶是否希望他將來被記住并自動登錄。
  2. 如果是這樣,請在他的計算機上使用登錄名和密碼保存cookie。
  3. 對于每個訪問我們網站的新用戶,請檢查是否存在步驟2中的cookie,如果存在,則為自動登錄用戶。
  4. 當他手動注銷時,請刪除cookie,以便可以清除用于自動登錄的數據。

第二點需要一些解釋。 在此示例應用程序中,我們將保存登錄信息,而不是哈希值,即 cookie中未加密的密碼。 在實際情況下,這是不可接受的。 取而代之的是,您應該考慮存儲散列和加鹽的密碼,這樣,即使有人攔截了用戶Cookie,密碼仍然是秘密的,需要更多的工作來對其進行解碼。
更新: Micha? Mat?oka發布了兩個非常有趣的鏈接,這些鏈接如何在實際系??統中完成。 這些方法甚至不使用密碼或密碼哈希。 有關更多詳細信息,請查看此帖子下方的他的評論。

第1步:作為用戶,我想決定是否要使用“記住我”功能

鏈接以提交此步驟

為了允許用戶通知應用程序他想使用“記住我”功能,我們只需在登錄頁面添加一個復選框即可。 因此,我們需要稍微修改LoginPage Java和html文件(突出顯示新內容):

<form wicket:id='form' class='form-horizontal'><fieldset><legend>Please login</legend></fieldset><div class='control-group'><div wicket:id='feedback'></div></div><div class='control-group'><label class='control-label' for='login'>Login</label><div class='controls'><input type='text' id='login' wicket:id='login' /></div></div><div class='control-group'><label class='control-label' for='password'>Password</label><div class='controls'><input type='password' id='password' wicket:id='password' /></div></div><div class='control-group'><div class='controls'><label class='checkbox'><input type='checkbox' wicket:id='rememberMe'> Remember me on this computer</label></div></div><div class='form-actions'><input type='submit' wicket:id='submit' value='Login' title='Login' class='btn btn-primary'/></div></form>
private String login;private String password;private boolean rememberMe;public LoginPage() {Form<Void> loginForm = new Form<Void>('form');add(loginForm);loginForm.add(new FeedbackPanel('feedback'));loginForm.add(new RequiredTextField<String>('login', new PropertyModel<String>(this, 'login')));loginForm.add(new PasswordTextField('password', new PropertyModel<String>(this, 'password')));loginForm.add(new CheckBox('rememberMe', new PropertyModel<Boolean>(this, 'rememberMe')));Button submit = new Button('submit') {// (...)};loginForm.add(submit);}

現在我們準備好下一步。

步驟2:作為系統,我想將登錄名和密碼保存在Cookie中

鏈接以提交此步驟

首先,我們需要一個CookieService,它將封裝負責處理cookie的所有邏輯:在需要時保存,列出和清除cookie。 代碼非常簡單,我們使用WebResponse和WebRequest類來修改用戶瀏覽器中的cookie。

public class CookieService {public Cookie loadCookie(Request request, String cookieName) {List<Cookie> cookies = ((WebRequest) request).getCookies();if (cookies == null) {return null;}for (Cookie cookie : cookies) {if(cookie.getName().equals(cookieName)) {return cookie;}}return null;}public void saveCookie(Response response, String cookieName, String cookieValue, int expiryTimeInDays) {Cookie cookie = new Cookie(cookieName, cookieValue);cookie.setMaxAge((int) TimeUnit.DAYS.toSeconds(expiryTimeInDays));((WebResponse)response).addCookie(cookie);}public void removeCookieIfPresent(Request request, Response response, String cookieName) {Cookie cookie = loadCookie(request, cookieName);if(cookie != null) {((WebResponse)response).clearCookie(cookie);}}
}

然后,當用戶在LoginPage上選中“記住我”時,我們必須在其瀏覽器中保存cookie:

Button submit = new Button('submit') {@Overridepublic void onSubmit() {UserService userService = WicketApplication.get().getUserService();User user = userService.findByLoginAndPassword(login, password);if(user == null) {error('Invalid login and/or password. Please try again.');}else {UserSession.get().setUser(user);if(rememberMe) {CookieService cookieService = WicketApplication.get().getCookieService();cookieService.saveCookie(getResponse(), REMEMBER_ME_LOGIN_COOKIE, user.getLogin(), REMEMBER_ME_DURATION_IN_DAYS);cookieService.saveCookie(getResponse(), REMEMBER_ME_PASSWORD_COOKIE, user.getPassword(), REMEMBER_ME_DURATION_IN_DAYS);}setResponsePage(HomePage.class);}}};

第3步:作為用戶,我想在返回Web應用程序時自動登錄

鏈接以提交此步驟

為了檢查用戶進入我們的應用程序是否是“使用戶自動登錄”,我們必須豐富負責創建新用戶會話的邏輯。 當前,它是在WicketApplication類中完成的,該類在被請求時創建新的WebSession實例。 因此,每次創建新會話時,我們都必須檢查cookie是否存在,以及它們是否為有效的用戶名/密碼對,請自動登錄該用戶。

因此,讓我們開始將與會話相關的邏輯提取到名為SessionProvider的單獨的類中。 它將需要UserService和CookieService來檢查現有用戶和cookie,因此我們將它們作為構造函數中的引用傳遞。

public class WicketApplication extends WebApplication {private UserService userService = new UserService();private CookieService cookieService = new CookieService();private SessionProvider sessionProvider = new SessionProvider(userService, cookieService);@Overridepublic Session newSession(Request request, Response response) {return sessionProvider.createNewSession(request);}
}

SessionProvider的作用是創建新的UserSession,檢查是否存在正確的cookie,如果存在,則設置登錄用戶。 此外,我們添加了反饋消息,以通知用戶他已被自動記錄。 因此,讓我們看一下代碼:

public class SessionProvider {public SessionProvider(UserService userService, CookieService cookieService) {this.userService = userService;this.cookieService = cookieService;}public WebSession createNewSession(Request request) {UserSession session = new UserSession(request);Cookie loginCookie = cookieService.loadCookie(request, REMEMBER_ME_LOGIN_COOKIE);Cookie passwordCookie = cookieService.loadCookie(request, REMEMBER_ME_PASSWORD_COOKIE);if(loginCookie != null && passwordCookie != null) {User user = userService.findByLoginAndPassword(loginCookie.getValue(), passwordCookie.getValue());if(user != null) {session.setUser(user);session.info('You were automatically logged in.');}}return session;}
}

為了在HomePage.java上顯示反饋消息,我們必須在該處添加FeedbackPanel,但是為了簡潔起見,我將在本文中省略它。 您可以閱讀commit來檢查如何做。

因此,經過三步,我們應該使“記住我”成為可能。 要快速檢查它,請通過添加以下內容來修改web.xml文件中的會話超時:

<session-config><session-timeout>1</session-timeout></session-config>

然后啟動應用程序mvn clean compile jetty:run ,進入登錄頁面,登錄,關閉瀏覽器,并在1分鐘后(會話終止時)在http:// localhost:8080上再次打開它。 您應該會看到以下內容:

這樣就可以了。 但是我們還需要做一件事:允許用戶刪除Cookie并關閉自動登錄。

第4步:作為用戶,我希望能夠注銷并清除我的Cookie

鏈接以提交此步驟 在最后一步,我們必須允許用戶清除其數據并禁用其帳戶的“記住我”。 這將通過在用戶明確單擊“注銷”鏈接時清除兩個cookie來實現。

Link<Void> logoutLink = new Link<Void>('logout') {@Overridepublic void onClick() {CookieService cookieService = WicketApplication.get().getCookieService();cookieService.removeCookieIfPresent(getRequest(), getResponse(), SessionProvider.REMEMBER_ME_LOGIN_COOKIE);cookieService.removeCookieIfPresent(getRequest(), getResponse(), SessionProvider.REMEMBER_ME_PASSWORD_COOKIE);UserSession.get().setUser(null);UserSession.get().invalidate();}};logoutLink.setVisible(UserSession.get().userLoggedIn());add(logoutLink);


摘要

就是這樣。 在此端口中,我們已經在使用Apache Wicket編寫的Web應用程序中實現了簡單的“記住我”功能,而無需使用任何外部身份驗證庫。

祝您編程愉快,別忘了分享!

參考:來自Code Hard Go Pro博客的JCG合作伙伴 Tomasz Dziurko的Apache Wicket中的“記住我”功能 。


翻譯自: https://www.javacodegeeks.com/2012/09/apache-wicket-remember-me-functionality.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/371614.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371614.shtml
英文地址,請注明出處:http://en.pswp.cn/news/371614.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu 安裝中文

系統環境&#xff1a; 1. 官網 http://pinyin.sogou.com/linux/ 下載安裝包。 2. 先運行 apt-get update 。 3. 再運行 apt-get -f install 。 4. 再運行 可能有的UBuntu系統自帶了。 5. 如果下載的搜狐輸入法安裝包的格式為 .deb 的&#xff0c; 運行 &#xff1a; dpk…

Eigen教程(10)

整理下Eigen庫的教程&#xff0c;參考&#xff1a;http://eigen.tuxfamily.org/dox/index.html 混淆 在Eigen中&#xff0c;當變量同時出現在左值和右值&#xff0c;賦值操作可能會帶來混淆問題。這一篇將解釋什么是混淆&#xff0c;什么時候是有害的&#xff0c;怎么使用做。 …

matlab把符號數,Matlab?符號與數值之間的轉換

符號運算得到的是精確的解析解&#xff0c;但是有時需要進行數值轉換&#xff0c;主要通過以下幾個函數實現。1.digits 函數調用方法&#xff1a;digits(D)函數設置有效數字個數為D的近似解精度。2.vpa 函數vpaVariable-precision arithmeticSyntaxR vpa(A)R vpa(A,d)Descrip…

JSF組件庫–質量不只是零缺陷

自從我上次研究三個主要JSF組件庫的質量以來&#xff0c;已經有一段時間了。 2009年12月&#xff0c;我開始比較RichFaces&#xff0c;Primefaces和ICEfaces的整體軟件質量 。 從那時起&#xff0c;事情發生了變化&#xff0c;從現在開始&#xff0c;我想重新評估和更新它。 我…

[API檔案]GetDlgItem

函數功能 用于獲取指定對話框函數控件的句柄。 API函數原型 1 HWND WINAPI GetDlgItem( 2 _In_opt_ HWND hDlg, //指向包含該對話框的句柄 3 _In_ int nIDDlgItem //第二個參數是控件的名稱 4 ); 范例 可參見ComboBox_AddString宏的范例【點擊這里】轉載于:ht…

嵌入式實時系統的任務設計

嵌入式實時系統的任務設計主要為任務函數的設計、任務優先級的安排、任務的數據結構設計&#xff0c;任務之間的同步與通信設計。 一&#xff0e;任務函數的設計 任務函數按任務結構可分為單次執行任務、周期執行任務和事件觸發任務&#xff0c;各任務的主要差異點如下&#xf…

mssql php 5.4,PHP5.4如何連接MSSql Server2005

windows系統下&#xff0c;PHP5.3以上的版本已經不支持mssql擴展&#xff0c;所以如果你需要和sql server通信需要到http://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx自行下載微軟提供的The SQL Server Driver for PHP。下載后解壓縮&#xff0c;將所有的.dll文件拷貝…

將原生SQL功能休眠到您的Spring Data Repository中

JPA為您提供NamedNativeQuery以便使用本機SQL。 但是&#xff0c;用法不是很方便&#xff0c;尤其是當您需要在本機SQL中映射多個實體時。 您必須定義一組容易出錯的SqlResultSetMapping映射。 對于以前使用過Hibernate本機SQL功能的用戶&#xff0c;您會發現它比JPA的NamedNat…

創建yii的第一個應用

原文鏈接轉載于:https://www.cnblogs.com/Baronboy/p/6354522.html

字符串匹配(KMP 算法 含代碼)

主要是針對字符串的匹配算法進行解說 有關字符串的基本知識傳統的串匹配法模式匹配的一種改進算法KMP算法網上一比較易懂的解說小樣例1計算next 2計算nextval代碼有關字符串的基本知識 串&#xff08;string或字符串&#xff09;是由零個或多個字符組成的有限序列&#xff0c;一…

php數組轉為js json,javascript-將數組php轉換為JSON時出錯

我在將多維PHP數組轉換為JSON時遇到了一些麻煩.我使用json_encode進行了轉換,但它為null.我正在嘗試開發orgChart,數據是從CSV文件中讀取的,并保存在數組中.布局和JS代碼用于接收JSON文件,因此我需要使用這種格式.這是數組的一部分,其中包含175個數組Array([2] > Array([id]…

UVa 10954 全部相加(Huffman編碼)

https://vjudge.net/problem/UVA-10954 題意&#xff1a;有n個數的集合S&#xff0c;每次可以從S中刪除兩個數&#xff0c;然后把它們的和放回集合&#xff0c;直到剩下一個數。每次操作的開銷等于刪除的兩個數之和&#xff0c;求最小開銷。 思路&#xff1a;Huffman編碼。 1 #…

serialVersionUID的作用以及如何用idea自動生成實體類的serialVersionUID

轉載&#xff1a;http://blog.csdn.net/liuzongl2012/article/details/45168585 serialVersionUID的作用&#xff1a; 通過判斷實體類的serialVersionUID來驗證版本一致性的。在進行反序列化時&#xff0c;JVM會把傳來的字節流中的serialVersionUID與本地相應實體類的serialVer…

js post方式請求另外一個php,利用JS使用POST方式提交請求的方法(結合代碼詳細解答)...

下面是我給大家整理的利用JS使用POST方式提交請求的方法&#xff0c;有興趣的同學可以去看看。一般都是寫上隱藏的form標簽&#xff0c;用來調用js函數然后submit全部用js來寫也行&#xff0c;以下是我在一個問答頻道看見別人寫的例子&#xff0c;放在這里function post(URL, P…

JBoss BRMS最佳實踐– BPM流程初始化層的提示

我過去發布過一些有關遷移策略的文章&#xff0c;仔細研究了流程層&#xff0c;并提供了一些有關jBPM的最佳實踐 &#xff0c;它們都涉及到BPM策略的非常具體的部分。 我想重新討論最佳實踐的主題&#xff0c;然后在智能集成企業級別上&#xff0c;我們討論使用JBoss BRMS對您的…

寒假作業二:匯總隨筆

隨筆一&#xff1a;解題思路隨筆二&#xff1a;自學計劃 轉載于:https://www.cnblogs.com/mercuialC/p/6359997.html

跨站點腳本(XSS)和預防

如OWASP網站&#xff08;https://www.owasp.org/index.php/Cross-site_Scripting_(XSS&#xff09;&#xff09;所述&#xff0c;跨站點腳本&#xff08;XSS&#xff09;攻擊的變種幾乎是無限的。 在這里&#xff0c;我建議使用基于Servlet篩選器的解決方案來清理HTTP請求。 攻…

NoSQL入門第一天——NoSQL入門與基本概述

一、課程大綱 二、入門概述 1.為什么用NoSQL 單機MySQL的年代&#xff1a; 一個網站的訪問量一般都不大&#xff0c;用單個數據庫完全可以輕松應付。      我們來看看數據存儲的瓶頸是什么&#xff1f;        1.數據量的總大小 一個機器放不下時。&#xff08;現…

隨機森林特征個數mtry matlab,基于隨機森林的特征選擇算法

2.1 算法描述本文提出了一種基于隨機森林的Wrapper特征選擇方法RFFS,利用隨機森林算法的變量重要性度量對特征進行排序,然后采用序列后向搜索方法,每次從特征集合中去掉一個最不重要(重要性得分最小)的特征,逐次進行迭代,并計算分類正確率,最終得到變量個數最少、分類正確率最高…

matlab循環讀取變量,Matlab for 多個變量循環能不能這樣啊 ,求教高手!!!!

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓for a0.003:0.0005:1; b0.002:0.0005:0.9; c0.001:0.0005:0.8;d0.0005:0.0005:0.7;E1a* E_Bone;E2b* E_Bone;E3c* E_Bone;E4d* E_Bone;G1a* G_Bone;G2b* G_Bone;G3c* G_Bone;G4d* G_Bone;%% Integration for cortical bone partsIn…