亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

正確優雅的解決用戶退出問題(轉自http://www.jdon.com)

2019-11-18 11:21:27
字體:
來源:轉載
供稿:網友

wolfmanchen 翻譯javaworld.com上名為<<Solving the logout PRoblem properly and elegantly>>的文章
原文地址: http://www.javaworld.com/javaworld/jw-09-2004/jw-0927-logout.Html

正確優雅的解決用戶退出問題——jsp和Struts解決方案

摘要
在一個有密碼保護的Web應用中,正確處理用戶退出過程并不僅僅只需調用Httpsession的invalidate()方法?,F在大部分瀏覽器上都有后退和前進按鈕,答應用戶后退或前進到一個頁面。假如在用戶在退出一個Web應用后按了后退按鈕瀏覽器把緩存中的頁面呈現給用戶,這會使用戶產生迷惑,他們會開始擔心他們的個人數據是否安全。許多Web應用強迫用戶退出時關閉整個瀏覽器,這樣,用戶就無法點擊后退按鈕了。還有一些使用javascript,但在某些客戶端瀏覽器這卻不一定起作用。這些解決方案都很笨拙且不能保證在任一情況下100%有效,同時,它也要求用戶有一定的操作經驗。
這篇文章以示例闡述了正確解決用戶退出問題的方案。作者Kevin Le首先描述了一個密碼保護Web應用,然后以示例程序解釋問題如何產生并討論解決問題的方案。文章雖然是針對JSP頁面進行闡述,但作者所闡述的概念很輕易理解切能夠為其他Web技術所采用。最后作者展示了如何用Jakarta Struts優雅地解決這一問題。




大部分Web應用不會包含象銀行賬戶或信用卡資料那樣機密的信息,但一旦涉及到敏感數據,我們就需要提供一類密碼保護機制。舉例來說,一個工廠中工人通過Web訪問他們的時間安排、進入他們的練習課程以及查看他們的薪金等等。此時應用SSL(Secure Socket Layer)有點殺雞用牛刀的感覺,但不可否認,我們又必須為這些應用提供密碼保護,否則,工人(也就是Web應用的使用者)可以窺探到工廠中其他雇員的私人機密信息。
與上述情形相似的還有位處圖書館、醫院等公共場所的計算機。在這些地方,許多用戶共同使用幾臺計算機,此時保護用戶的個人數據就顯得至關重要。設計良好編寫優秀的應用對用戶專業知識的要求少之又少。
我們來看一下現實世界中一個完美的Web應用是如何表現的:一個用戶通過瀏覽器訪問一個頁面。Web應用展現一個登陸頁面要求用戶輸入有效的驗證信息。用戶輸入了用戶名和密碼。此時我們假設用戶提供的身份驗證信息是正確的,經過了驗證過程,Web應用答應用戶瀏覽他有權訪問的區域。用戶想退出時,點擊退出按鈕,Web應用要求用戶確認他是否則真的需要退出,假如用戶確定退出,Session結束,Web應用重新定位到登陸頁面。用戶可以放心的離開而不用擔心他的信息會泄露。另一個用戶坐到了同一臺電腦前,他點擊后退按鈕,Web應用不應該出現上一個用戶訪問過的任何一個頁面。事實上,Web應用在第二個用戶提供正確的驗證信息之前應當一直停留在登陸頁面上。
通過示例程序,文章向您闡述了如何在一個Web應用中實現這一功能。

JSP samples
為了更為有效地闡述實現方案,本文將從展示一個示例應用logoutSampleJSP1中碰到的問題開始。這個示例代表了許多沒有正確解決退出過程的Web應用。logoutSampleJSP1包含了下述jsp頁面:login.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中頁面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不答應未經認證的用戶訪問的,也就是說,這些頁面包含了重要信息,在用戶登陸之前或者退出之后都不應該出現在瀏覽器中。login.jsp包含了用于用戶輸入用戶名和密碼的form。logout.jsp頁包含了要求用戶確認是否退出的form。loginAction.jsp和logoutAction.jsp作為控制器分別包含了登陸和退出代碼。
第二個示例應用logoutSampleJSP2展示了如何解決示例logoutSampleJSP1中的問題。然而,第二個應用自身也是有疑問的。在特定的情況下,退出問題還是會出現。
第三個示例應用logoutSampleJSP3在第二個示例上進行了改進,比較完善地解決了退出問題。
最后一個示例logoutSampleStruts展示了Struts如何美麗地解決登陸問題。
注重:本文所附示例在最新版本的Microsoft Internet EXPlorer (IE), Netscape Navigator, Mozilla, Firefox和Avant瀏覽器上測試通過。

Login action
Brian Pontarelli的經典文章《J2EE Security: Container Versus Custom》討論了不同的J2EE認證途徑。文章同時指出,HTTP協議和基于form的認證并未提供處理用戶退出的機制。因此,解決途徑便是引入自定義的安全實現機制。
自定義的安全認證機制普遍采用的方法是從form中獲得用戶輸入的認證信息,然后到諸如LDAP (lightweight Directory access protocol)或關系數據庫的安全域中進行認證。假如用戶提供的認證信息是有效的,登陸動作往HttpSession對象中注入某個對象。HttpSession存在著注入的對象則表示用戶已經登陸。為了方便讀者理解,本文所附的示例只往HttpSession中寫入一個用戶名以表明用戶已經登陸。清單1是從loginAction.jsp頁面中節選的一段代碼以此闡述登陸動作:




Listing 1
//...
//initialize RequestDispatcher object; set forward to home page by default
RequestDispatcher rd = request.getRequestDispatcher("home.jsp");

//Prepare connection and statement
rs = stmt.executeQuery("select passWord from USER where userName = '" + userName + "'");
if (rs.next()) { //Query only returns 1 record in the result set; only 1
password per userName which is also the primary key
if (rs.getString("password").equals(password)) { //If valid password
session.setAttribute("User", userName); //Saves username string in the session object
}
else { //Password does not match, i.e., invalid user password
request.setAttribute("Error", "Invalid password.");

rd = request.getRequestDispatcher("login.jsp");
}
} //No record in the result set, i.e., invalid username
else {

request.setAttribute("Error", "Invalid user name.");
rd = request.getRequestDispatcher("login.jsp");
}
}

//As a controller, loginAction.jsp finally either forwards to "login.jsp" or "home.jsp"
rd.forward(request, response);
//...


本文所附示例均以關系型數據庫作為安全域,但本問所闡述的觀點對任何類型的安全域都是適用的。

Logout action
退出動作就包含了簡單的刪除用戶名以及對用戶的HttpSession對象調用invalidate()方法。清單2是從loginoutAction.jsp頁面中節選的一段代碼以此闡述退出動作:



Listing 2
//...
session.removeAttribute("User");
session.invalidate();
//...


阻止未經認證訪問受保護的JSP頁面
從form中獲取用戶提交的認證信息并經過驗證后,登陸動作簡單地往 HttpSession對象中寫入一個用戶名,退出動作則做相反的工作,它從用戶的HttpSession對象中刪除用戶名并調用invalidate()方法銷毀HttpSession。為了使登陸和退出動作真正發揮作用,所有受保護的JSP頁面都應該首先驗證HttpSession中是否包含了用戶名以確認當前用戶是否已經登陸。假如HttpSession中包含了用戶名,也就是說用戶已經登陸,Web應用則將剩余的JSP頁發送給瀏覽器,否則,JSP頁將跳轉到登陸頁login.jsp。頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp均包含清單3中的代碼段:


Listing 3
//...
String userName = (String) session.getAttribute("User");
if (null == userName) {
request.setAttribute("Error", "Session has ended. Please login.");
RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
rd.forward(request, response);
}
//...
//Allow the rest of the dynamic content in this JSP to be served to the browser
//...


在這個代碼段中,程序從HttpSession中減縮username字符串。假如字符串為空,Web應用則自動中止執行當前頁面并跳轉到登陸頁,同時給出Session has ended. Please log in.的提示;假如不為空,Web應用則繼續執行,也就是把剩余的頁面提供給用戶。
運行logoutSampleJSP1
運行logoutSampleJSP1將會出現如下幾種情形:
• 假如用戶沒有登陸,Web應用將會正確中止受保護頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的執行,也就是說,假如用戶在瀏覽器地址欄中直接敲入受保護JSP頁的地址試圖訪問,Web應用將自動跳轉到登陸頁并提示Session has ended.Please log in.
• 同樣的,當一個用戶已經退出,Web應用也會正確中止受保護頁面home.jsp, secure1.jsp, secure2.jsp和logout.jsp的執行
• 用戶退出后,假如點擊瀏覽器上的后退按鈕,Web應用將不能正確保護受保護的頁面——在Session銷毀后(用戶退出)受保護的JSP頁重新在瀏覽器中顯示出來。然而,假如用戶點擊返回頁面上的任何鏈接,Web應用將會跳轉到登陸頁面并提示Session has ended.Please log in.
阻止瀏覽器緩存
上述問題的根源在于大部分瀏覽器都有一個后退按鈕。當點擊后退按鈕時,默認情況下瀏覽器不是從Web服務器上重新獲取頁面,而是從瀏覽器緩存中載入頁面。基于Java的Web應用并未限制這一功能,在基于php、asp和.NET的Web應用中也同樣存在這一問題。
在用戶點擊后退按鈕后,瀏覽器到服務器再從服務器到瀏覽器這樣通常意思上的HTTP回路并沒有建立,僅僅只是用戶,瀏覽器和緩存進行了交互。所以,即使包含了清單3上的代碼來保護JSP頁面,當點擊后退按鈕時,這些代碼是不會執行的。
緩存的好壞,真是仁者見仁智者見智。緩存的確提供了一些便利,但通常只在使用靜態的HTML頁面或基于圖形或影響的頁面你才能感受到。而另一方面,Web應用通常是基于數據的,數據通常是頻繁更改的。與從緩存中讀取并顯示過期的數據相比,提供最新的數據才是更重要的!
幸運的是,HTTP頭信息“Expires”和“Cache-Control”為應用程序服務器提供了一個控制瀏覽器和代理服務器上緩存的機制。HTTP頭信息Expires告訴代理服務器它的緩存頁面何時將過期。HTTP1.1規范中新定義的頭信息Cache-Control可以通知瀏覽器不緩存任何頁面。當點擊后退按鈕時,瀏覽器重新訪問服務器已獲取頁面。如下是使用Cache-Control的基本方法:
• no-cache:強制緩存從服務器上獲取新的頁面
• no-store: 在任何環境下緩存不保存任何頁面
HTTP1.0規范中的Pragma:no-cache等同于HTTP1.1規范中的Cache-Control:no-cache,同樣可以包含在頭信息中。
通過使用HTTP頭信息的cache控制,第二個示例應用logoutSampleJSP2解決了logoutSampleJSP1的問題。logoutSampleJSP2與logoutSampleJSP1不同表現在如下代碼段中,這一代碼段加入進所有受保護的頁面中:




//...
response.setHeader("Cache-Control","no-cache"); //Forces caches to oBTain a new copy of the page from the origin server
response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance
response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"
response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility
String userName = (String) session.getAttribute("User");
if (null == userName) {
request.setAttribute("Error", "Session has ended. Please login.");
RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
rd.forward(request, response);
}
//...


通過設置頭信息和檢查HttpSession中的用戶名確保了瀏覽器不緩存頁面,同時,假如用戶未登陸,受保護的JSP頁面將不會發送到瀏覽器,取而代之的將是登陸頁面login.jsp。
運行logoutSampleJSP2
運行logoutSampleJSP2后將回看到如下結果:
• 當用戶退出后試圖點擊后退按鈕,瀏覽器并不會顯示受保護的頁面,它只會現實登陸頁login.jsp同時給出提示信息Session has ended. Please log in.
• 然而,當按了后退按鈕返回的頁是處理用戶提交數據的頁面時,IE和Avant瀏覽器將彈出如下信息提示:
警告:頁面已過期……(你肯定見過)
選擇刷新后前一個JSP頁面將重新顯示在瀏覽器中。很顯然,這不是我們所想看到的因為它違反了logout動作的目的。發生這一現象時,很可能是一個惡意用戶在嘗試獲取其他用戶的數據。然而,這個問題僅僅出現在后退按鈕對應的是一個處理POST請求的頁面。
記錄最后登陸時間
上述問題之所以出現是因為瀏覽器將其緩存中的數據重新提交了。這本文的例子中,數據包含了用戶名和密碼。無論是否給出安全警告信息,瀏覽器此時起到了負面作用。
為了解決logoutSampleJSP2中出現的問題,logoutSampleJSP3的login.jsp在包含username和password的基礎上還包含了一個稱作lastLogon的隱藏表單域,此表單域動態的用一個long型值初始化。這個long型值是調用System.currentTimeMillis()獲取到的自1970年1月1日以來的毫秒數。當login.jsp中的form提交時,loginAction.jsp首先將隱藏域中的值與用戶數據庫中的值進行比較。只有當lastLogon表單域中的值大于數據庫中的值時Web應用才認為這是個有效的登陸。
為了驗證登陸,數據庫中lastLogon字段必須以表單中的lastLogon值進行更新。上例中,當瀏覽器重復提交數據時,表單中的lastLogon值不比數據庫中的lastLogon值大,因此,loginAction轉到login.jsp頁面,并提示Session has ended.Please log in.清單5是loginAction中節選的代碼段:




清單5
//...
RequestDispatcher rd = request.getRequestDispatcher("home.jsp"); //Forward to homepage by default
//...
if (rs.getString("password").equals(password)) { //If valid password
long lastLogonDB = rs.getLong("lastLogon");
if (lastLogonForm > lastLogonDB) {
session.setAttribute("User", userName); //Saves username string in the session object
stmt.executeUpdate("update USER set lastLogon= " + lastLogonForm + " where userName = '" + userName + "'");
}
else {
request.setAttribute("Error", "Session has ended. Please login.");
rd = request.getRequestDispatcher("login.jsp"); }
}
else { //Password does not match, i.e., invalid user password
request.setAttribute("Error", "Invalid password.");
rd = request.getRequestDispatcher("login.jsp");
}
//...
rd.forward(request, response);
//...


為了實現上述方法,你必須記錄每個用戶的最后登陸時間。對于采用關系型數據庫安全域來說,這點可以可以通過在某個表中加上lastLogin字段輕松實現。LDAP以及其他的安全域需要稍微動下腦筋,但很顯然是可以實現的。
表示最后登陸時間的方法有很多。示例logoutSampleJSP3利用了自1970年1月1日以來的毫秒數。這個方法在許多人在不同瀏覽器中用一個用戶賬號登陸時也是可行的。
運行logoutSampleJSP3
運行示例logoutSampleJSP3將展示如何正確處理退出問題。一旦用戶退出,點擊瀏覽器上的后退按鈕在任何情況下都不會是受保護的頁面在瀏覽器上顯示出來。這個示例展示了如何正確處理退出問題而不需要額外的培訓。
為了使代碼更簡練有效,一些冗余的代碼可以剔除掉。一種途徑就是把清單4中的代碼寫到一個單獨的JSP頁中,通過標簽其他頁面也可以引用。
Struts框架下的退出實現
與直接使用JSP或JSP/servlets相比,另一個可選的方案是使用Struts。為一個基于Struts的Web應用添加一個處理退出問題的框架可以優雅地不費氣力的實現。這部分歸功于Struts是采用MVC設計模式的因此將模型和視圖清楚的分開。另外,Java是一個面向對象的語言,其支持繼續,可以比JSP中的腳本更為輕易地實現代碼重用。在Struts中,清單4中的代碼可以從JSP頁面中移植到Action類的execute()方法中。
此外,我們還可以定義一個繼續Struts Action類的基本類,其execute()方法中包含了清單4中的代碼。通過使用類繼續機制,其他類可以繼續基本類中的通用邏輯來設置HTTP頭信息以及檢索HttpSession對象中的username字符串。這個基本類是一個抽象類并定義了一個抽象方法executeAction()。所有繼續自基類的子類都應實現exectuteAction()方法而不是覆蓋它。清單6是基類的部分代碼:



清單6
public abstract class BaseAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {

response.setHeader("Cache-Control","no-cache"); //Forces caches to obtain a new copy of the page from the origin server
response.setHeader("Cache-Control","no-store"); //Directs caches not to store the page under any circumstance
response.setDateHeader("Expires", 0); //Causes the proxy cache to see the page as "stale"
response.setHeader("Pragma","no-cache"); //HTTP 1.0 backward compatibility

if (!this.userIsLoggedIn(request)) {
ActionErrors errors = new ActionErrors();

errors.add("error", new ActionError("logon.sessionEnded"));
this.saveErrors(request, errors);

return mapping.findForward("sessionEnded");
}

return executeAction(mapping, form, request, response);
}

protected abstract ActionForward executeAction(ActionMapping mapping,
ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;

private boolean userIsLoggedIn(HttpServletRequest request) {
if (request.getSession().getAttribute("User") == null) {
return false;
}

return true;
}
}


清單6中的代碼與清單4中的很相像,僅僅只是用ActionMapping findForward替代了RequestDispatcher forward。清單6中,假如在HttpSession中未找到username字符串,ActionMapping對象將找到名為sessionEnded的forward元素并跳轉到對應的path。假如找到了,子類將執行其實現了executeAction()方法的業務邏輯。因此,在配置文件struts-web.xml中為所有子類聲明個一名為sessionEnded的forward元素是必須的。清單7以secure1 action闡明了這樣一個聲明:


清單7
<action path="/secure1"
type="com.kevinhle.logoutSampleStruts.Secure1Action"
scope="request">
<forward name="sUCcess" path="/WEB-INF/jsps/secure1.jsp"/>
<forward name="sessionEnded" path="/login.jsp"/>
</action>



繼續自BaseAction類的子類Secure1Action實現了executeAction()方法而不是覆蓋它。Secure1Action類不執行任何退出代碼,如清單8:



清單8
public class Secure1Action extends BaseAction {
public ActionForward executeAction(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {

HttpSession session = request.getSession();
return (mapping.findForward("success"));
}
}


只需要定義一個基類而不需要額外的代碼工作,上述解決方案是優雅而有效的。不管怎樣,將通用的行為方法寫成一個繼續StrutsAction的基類是許多Struts項目的共同經驗,值得推薦。
局限性
上述解決方案對JSP或基于Struts的Web應用都是非常簡單而實用的,但它還是有某些局限。在我看來,這些局限并不是至關緊要的。
結論
本文闡述了解決退出問題的方案,盡管方案簡單的令人驚奇,但卻在所有情況下都能有效地工作。無論是對JSP還是Struts,所要做的不過是寫一段不超過50行的代碼以及一個記錄用戶最后登陸時間的方法。在Web應用中混合使用這些方案能夠使擁護的私人數據不致泄露,同時,也能增加用戶的經驗。

About the author
Kevin H. Le has more than 12 years of experience in software development. In the first half of his career, his programming language of choice was C++. In 1997, he shifted his focus to Java. He has engaged in and successfully completed several J2EE and EAI projects as both developer and architect. In addition to J2EE, his current interests now include Web services and SOA. More information on Kevin can be found on his Website http://kevinhle.com.



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩hd视频在线观看| 性色av一区二区三区红粉影视| 国产精品久久久久9999| 亚洲午夜精品视频| 91精品久久久久久久久久另类| 亚洲老头同性xxxxx| 夜夜嗨av一区二区三区四区| 亚洲成人aaa| 久久综合久久美利坚合众国| 久久久91精品国产| 欧美亚洲日本网站| 欧美成人一二三| 日韩在线精品一区| 精品呦交小u女在线| 欧美性生交xxxxx久久久| 精品视频在线导航| 最近2019年日本中文免费字幕| 国产精品视频久久| 精品免费在线观看| 亚洲级视频在线观看免费1级| 欧美理论电影在线观看| 日韩电影中文字幕在线| 亚洲福利视频网| 国产精品入口日韩视频大尺度| 欧美性极品xxxx娇小| 欧美在线视频在线播放完整版免费观看| 欧美激情亚洲国产| 亚洲乱亚洲乱妇无码| 日韩三级影视基地| 国产国产精品人在线视| 日本高清不卡的在线| 中文字幕最新精品| 国产精品小说在线| 欧美黑人又粗大| 久久伊人精品视频| 精品欧美一区二区三区| 精品久久在线播放| 久久在线免费观看视频| 中文字幕在线观看日韩| 亲子乱一区二区三区电影| 欧美丝袜一区二区| 欧美日韩一区二区在线| 中文字幕亚洲综合久久| 午夜伦理精品一区| 国产在线精品成人一区二区三区| 亚洲精品一区在线观看香蕉| 日本亚洲欧美成人| 国产欧美一区二区三区在线| 成人综合网网址| 国产婷婷色综合av蜜臀av| 亚洲自拍在线观看| 亚洲女人被黑人巨大进入| 久久久精品国产一区二区| 欧美巨乳在线观看| 日韩一区二区福利| 欧美日韩国产91| 国内免费精品永久在线视频| 久久久久999| 日韩电影大全免费观看2023年上| 成人网在线免费看| 国产在线精品自拍| 7m第一福利500精品视频| 91精品久久久久久久久不口人| 国产成人涩涩涩视频在线观看| 欧洲成人在线视频| 国产成人精品久久亚洲高清不卡| 亚洲天堂日韩电影| 日韩欧美有码在线| 日韩精品在线影院| 午夜精品一区二区三区在线视| 日韩有码在线播放| 国产精品丝袜白浆摸在线| 国产va免费精品高清在线| 亚洲女性裸体视频| 亚洲电影免费观看高清完整版| 91久久精品国产91久久性色| 97碰碰碰免费色视频| 欧美亚洲在线视频| 久久久国产精品亚洲一区| 欧美人与物videos| 2019中文字幕在线免费观看| 日本老师69xxx| 26uuu另类亚洲欧美日本老年| 中文字幕亚洲无线码a| 97国产精品人人爽人人做| 亚洲一区二区三区久久| 日本高清视频精品| 国产精品久久久久77777| 日韩视频在线一区| 国产精品爽黄69| 九九综合九九综合| 久久精品国产96久久久香蕉| 夜夜嗨av色综合久久久综合网| 亚洲深夜福利网站| 欧美刺激性大交免费视频| 久久国产精品免费视频| 亚洲精品女av网站| 日日噜噜噜夜夜爽亚洲精品| 日韩精品999| 久久影院资源网| 欧美精品久久久久a| 国产v综合v亚洲欧美久久| 日韩精品中文字幕在线| 久久久免费在线观看| 久久99久久99精品免观看粉嫩| 国产成人一区三区| 在线激情影院一区| 久久久99久久精品女同性| 亚洲一区二区免费| 欧美日韩亚洲一区二| 国产精品一久久香蕉国产线看观看| 国产91精品在线播放| 欧美人交a欧美精品| 亚洲精品国产精品乱码不99按摩| 九九热99久久久国产盗摄| 成人激情视频免费在线| 国产一区二区在线播放| 成人黄色午夜影院| 日本午夜人人精品| 久久久噜噜噜久久中文字免| 久色乳综合思思在线视频| 欧美精品情趣视频| 亚洲第一色在线| 欧美日韩成人在线播放| 日韩成人激情影院| 国产精品成熟老女人| 色综合老司机第九色激情| 国产精品88a∨| 亚洲综合色av| 国产性色av一区二区| 久久国产精品首页| 欧洲s码亚洲m码精品一区| 日韩欧美在线视频免费观看| 亚洲第一综合天堂另类专| 国产ts人妖一区二区三区| 国产成人精品日本亚洲| 国产成人欧美在线观看| 国产精品久久久久9999| 97国产一区二区精品久久呦| 亚洲18私人小影院| 国产在线精品自拍| 国产一区二区欧美日韩| 91精品国产色综合久久不卡98| 久久久久久久久综合| 国产精品欧美在线| 亚洲免费av网址| 欧美精品激情在线观看| 都市激情亚洲色图| 95av在线视频| 91av视频导航| 91精品国产网站| 川上优av一区二区线观看| 色老头一区二区三区| 日韩欧美在线免费观看| 欧美激情精品久久久久久蜜臀| 中文字幕在线观看日韩| 欧美二区乱c黑人| 亚洲精品99久久久久中文字幕| 人人爽久久涩噜噜噜网站| 亚洲图中文字幕| 国产综合在线观看视频| 国产精品一区二区久久| 亚洲人成电影在线观看天堂色| 中文字幕国产精品久久|