中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

詳解ASP.NET MVC Form表單驗證
來源:易賢網(wǎng) 閱讀:1279 次 日期:2016-08-10 15:41:48
溫馨提示:易賢網(wǎng)小編為您整理了“詳解ASP.NET MVC Form表單驗證”,方便廣大網(wǎng)友查閱!

這篇文章主要為大家詳細(xì)介紹了ASP.NET MVC Form表單驗證,一般驗證方式有Windows驗證和表單驗證,web項目用得更多的是表單驗證,感興趣的小伙伴們可以參考一下

一、前言

關(guān)于表單驗證,已經(jīng)有不少的文章,相信Web開發(fā)人員也都基本寫過,最近在一個個人項目中剛好用到,在這里與大家分享一下。本來想從用戶注冊開始寫起,但發(fā)現(xiàn)東西比較多,涉及到界面、前端驗證、前端加密、后臺解密、用戶密碼Hash、權(quán)限驗證等等,文章寫起來可能會很長,所以這里主要介紹的是登錄驗證和權(quán)限控制部分,有興趣的朋友歡迎一起交流。

一般驗證方式有Windows驗證和表單驗證,web項目用得更多的是表單驗證。原理很簡單,簡單地說就是利用瀏覽器的cookie,將驗證令牌存儲在客戶端瀏覽器上,cookie每次會隨請求發(fā)送到服務(wù)器,服務(wù)器驗證這個令牌。通常一個系統(tǒng)的用戶會分為多種角色:匿名用戶、普通用戶和管理員;這里面又可以再細(xì)分,例如用戶可以是普通用戶或Vip用戶,管理員可以是普通管理員或超級管理員等。在項目中,我們有的頁面可能只允許管理員查看,有的只允許登錄用戶查看,這就是角色區(qū)分(Roles);某些特別情況下,有些頁面可能只允許叫“張三”名字的人查看,這就是用戶區(qū)分(Users)。

我們先看一下最后要實現(xiàn)的效果:

1.這是在Action級別的控制。

public class Home1Controller : Controller

{

  //匿名訪問

  public ActionResult Index()

  {

    return View();

  }

  //登錄用戶訪問

  [RequestAuthorize]

  public ActionResult Index2()

  {

    return View();

  }

  //登錄用戶,張三才能訪問

  [RequestAuthorize(Users="張三")]

  public ActionResult Index3()

  {

    return View();

  }

  //管理員訪問

  [RequestAuthorize(Roles="Admin")]

  public ActionResult Index4()

  {

    return View();

  }

}

2.這是在Controller級別的控制。當(dāng)然,如果某個Action需要匿名訪問,也是允許的,因為控制級別上,Action優(yōu)先級大于Controller。

//Controller級別的權(quán)限控制

[RequestAuthorize(User="張三")]

public class Home2Controller : Controller

{

  //登錄用戶訪問

  public ActionResult Index()

  {

    return View();

  }

  //允許匿名訪問

  [AllowAnonymous]

  public ActionResult Index2()

  {

    return View();

  }

}

3.Area級別的控制。有時候我們會把一些模塊做成分區(qū),當(dāng)然這里也可以在Area的Controller和Action進(jìn)行標(biāo)記。

從上面可以看到,我們需要在各個地方進(jìn)行標(biāo)記權(quán)限,如果把Roles和Users硬寫在程序中,不是很好的做法。我希望能更簡單一點,在配置文件進(jìn)行說明。例如如下配置:

<?xml version="1.0" encoding="utf-8" ?>

<!--

  1.這里可以把權(quán)限控制轉(zhuǎn)移到配置文件,這樣就不用在程序中寫roles和users了

  2.如果程序也寫了,那么將覆蓋配置文件的。

  3.action級別的優(yōu)先級 > controller級別 > Area級別  

-->

<root>

 <!--area級別-->

 <area name="Admin">

  <roles>Admin</roles>

 </area>

 <!--controller級別-->

 <controller name="Home2">

  <user>張三</user>

 </controller>

 <!--action級別-->

 <controller name="Home1">

  <action name="Inde3">

   <users>張三</users>

  </action>

  <action name="Index4">

   <roles>Admin</roles>

  </action>

 </controller>

</root>

寫在配置文件里,是為了方便管理,如果程序里也寫了,將覆蓋配置文件的。ok,下面進(jìn)入正題。

二、主要接口

先看兩個主要用到的接口。

IPrincipal 定義了用戶對象的基本功能,接口定義如下:

public interface IPrincipal

{

  //標(biāo)識對象

  IIdentity Identity { get; }

  //判斷當(dāng)前角色是否屬于指定的角色

  bool IsInRole(string role);

}

它有兩個主要成員,IsInRole用于判斷當(dāng)前對象是否屬于指定角色的,IIdentity定義了標(biāo)識對象信息。HttpContext的User屬性就是IPrincipal類型的。

IIdentity 定義了標(biāo)識對象的基本功能,接口定義如下:

public interface IIdentity

{  

  //身份驗證類型

  string AuthenticationType { get; }

  //是否驗證通過

  bool IsAuthenticated { get; } 

  //用戶名

  string Name { get; }

}

IIdentity包含了一些用戶信息,但有時候我們需要存儲更多信息,例如用戶ID、用戶角色等,這些信息會被序列到cookie中加密保存,驗證通過時可以解碼再反序列化獲得,狀態(tài)得以保存。例如定義一個UserData。

public class UserData : IUserData

{

  public long UserID { get; set; }

  public string UserName { get; set; }

  public string UserRole { get; set; }

  public bool IsInRole(string role)

  {

    if (string.IsNullOrEmpty(role))

    {

      return true;

    }

    return role.Split(',').Any(item => item.Equals(this.UserRole, StringComparison.OrdinalIgnoreCase));      

  }

  public bool IsInUser(string user)

  {

    if (string.IsNullOrEmpty(user))

    {

      return true;

    }

    return user.Split(',').Any(item => item.Equals(this.UserName, StringComparison.OrdinalIgnoreCase));

  }

}

UserData實現(xiàn)了IUserData接口,該接口定義了兩個方法:IsInRole和IsInUser,分別用于判斷當(dāng)前用戶角色和用戶名是否符合要求。該接口定義如下:

public interface IUserData

{

  bool IsInRole(string role);

  bool IsInUser(string user);

}

接下來定義一個Principal實現(xiàn)IPrincipal接口,如下:

public class Principal : IPrincipal    

{

  public IIdentity Identity{get;private set;}

  public IUserData UserData{get;set;}

  public Principal(FormsAuthenticationTicket ticket, IUserData userData)

  {

    EnsureHelper.EnsureNotNull(ticket, "ticket");

    EnsureHelper.EnsureNotNull(userData, "userData");

    this.Identity = new FormsIdentity(ticket);

    this.UserData = userData;

  }

  public bool IsInRole(string role)

  {

    return this.UserData.IsInRole(role);      

  }   

  public bool IsInUser(string user)

  {

    return this.UserData.IsInUser(user);

  }

}

Principal包含IUserData,而不是具體的UserData,這樣很容易更換一個UserData而不影響其它代碼。Principal的IsInRole和IsInUser間接調(diào)用了IUserData的同名方法。

三、寫入cookie和讀取cookie

接下來,需要做的就是用戶登錄成功后,創(chuàng)建UserData,序列化,再利用FormsAuthentication加密,寫到cookie中;而請求到來時,需要嘗試將cookie解密并反序列化。如下:

public class HttpFormsAuthentication

{    

  public static void SetAuthenticationCookie(string userName, IUserData userData, double rememberDays = 0)            

  {

    EnsureHelper.EnsureNotNullOrEmpty(userName, "userName");

    EnsureHelper.EnsureNotNull(userData, "userData");

    EnsureHelper.EnsureRange(rememberDays, "rememberDays", 0);

    //保存在cookie中的信息

    string userJson = JsonConvert.SerializeObject(userData);

    //創(chuàng)建用戶票據(jù)

    double tickekDays = rememberDays == 0 ? 7 : rememberDays;

    var ticket = new FormsAuthenticationTicket(2, userName,

      DateTime.Now, DateTime.Now.AddDays(tickekDays), false, userJson);

    //FormsAuthentication提供web forms身份驗證服務(wù)

    //加密

    string encryptValue = FormsAuthentication.Encrypt(ticket);

    //創(chuàng)建cookie

    HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptValue);

    cookie.HttpOnly = true;

    cookie.Domain = FormsAuthentication.CookieDomain;

    if (rememberDays > 0)

    {

      cookie.Expires = DateTime.Now.AddDays(rememberDays);

    }      

    HttpContext.Current.Response.Cookies.Remove(cookie.Name);

    HttpContext.Current.Response.Cookies.Add(cookie);

  }

  public static Principal TryParsePrincipal<TUserData>(HttpContext context)              

    where TUserData : IUserData

  {

    EnsureHelper.EnsureNotNull(context, "context");

    HttpRequest request = context.Request;

    HttpCookie cookie = request.Cookies[FormsAuthentication.FormsCookieName];

    if(cookie == null || string.IsNullOrEmpty(cookie.Value))

    {

      return null;

    }

    //解密cookie值

    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);

    if(ticket == null || string.IsNullOrEmpty(ticket.UserData))          

    {

      return null;            

    }

    IUserData userData = JsonConvert.DeserializeObject<TUserData>(ticket.UserData);       

    return new Principal(ticket, userData);

  }

}

在登錄時,我們可以類似這樣處理:

public ActionResult Login(string userName,string password)

{

  //驗證用戶名和密碼等一些邏輯... 

  UserData userData = new UserData()

  {

    UserName = userName,

    UserID = userID,

    UserRole = "Admin"

  };

  HttpFormsAuthentication.SetAuthenticationCookie(userName, userData, 7);

  //驗證通過...

}

登錄成功后,就會把信息寫入cookie,可以通過瀏覽器觀察請求,就會有一個名稱為"Form"的Cookie(還需要簡單配置一下配置文件),它的值是一個加密后的字符串,后續(xù)的請求根據(jù)此cookie請求進(jìn)行驗證。具體做法是在HttpApplication的AuthenticateRequest驗證事件中調(diào)用上面的TryParsePrincipal,如:

protected void Application_AuthenticateRequest(object sender, EventArgs e)

{

  HttpContext.Current.User = HttpFormsAuthentication.TryParsePrincipal<UserData>(HttpContext.Current);

}

這里如果驗證不通過,HttpContext.Current.User就是null,表示當(dāng)前用戶未標(biāo)識。但在這里還不能做任何關(guān)于權(quán)限的處理,因為上面說到的,有些頁面是允許匿名訪問的。

三、AuthorizeAttribute

這是一個Filter,在Action執(zhí)行前執(zhí)行,它實現(xiàn)了IActionFilter接口。關(guān)于Filter,可以看我之前的這篇文章,這里就不多介紹了。我們定義一個RequestAuthorizeAttribute繼承AuthorizeAttribute,并重寫它的OnAuthorization方法,如果一個Controller或者Action標(biāo)記了該特性,那么該方法就會在Action執(zhí)行前被執(zhí)行,在這里判斷是否已經(jīng)登錄和是否有權(quán)限,如果沒有則做出相應(yīng)處理。具體代碼如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]

public class RequestAuthorizeAttribute : AuthorizeAttribute

{

  //驗證

  public override void OnAuthorization(AuthorizationContext context)

  {

    EnsureHelper.EnsureNotNull(context, "httpContent");      

    //是否允許匿名訪問

    if (context.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), false))

    {

      return;

    }

    //登錄驗證

    Principal principal = context.HttpContext.User as Principal;

    if (principal == null)

    {

      SetUnAuthorizedResult(context);

      HandleUnauthorizedRequest(context);

      return;

    }

    //權(quán)限驗證

    if (!principal.IsInRole(base.Roles) || !principal.IsInUser(base.Users))

    {

      SetUnAuthorizedResult(context);

      HandleUnauthorizedRequest(context);

      return;

    }

    //驗證配置文件

    if(!ValidateAuthorizeConfig(principal, context))

    {

      SetUnAuthorizedResult(context);

      HandleUnauthorizedRequest(context);

      return;

    }      

  }

  //驗證不通過時

  private void SetUnAuthorizedResult(AuthorizationContext context)

  {

    HttpRequestBase request = context.HttpContext.Request;

    if (request.IsAjaxRequest())

    {

      //處理ajax請求

      string result = JsonConvert.SerializeObject(JsonModel.Error(403));        

      context.Result = new ContentResult() { Content = result };

    }

    else

    {

      //跳轉(zhuǎn)到登錄頁面

      string loginUrl = FormsAuthentication.LoginUrl + "?ReturnUrl=" + preUrl;

      context.Result = new RedirectResult(loginUrl);

    }

  }

//override

  protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)

  {

    if(filterContext.Result != null)

    {

      return;

    }

    base.HandleUnauthorizedRequest(filterContext);

  }

}

注:這里的代碼摘自個人項目中的,簡寫了部分代碼,有些是輔助類,代碼沒有貼出,但應(yīng)該不影響閱讀。

1. 如果我們在HttpApplication的AuthenticateRequest事件中獲得的IPrincipal為null,那么驗證不通過。

2. 如果驗證通過,程序會進(jìn)行驗證AuthorizeAttribute的Roles和User屬性。

3. 如果驗證通過,程序會驗證配置文件中對應(yīng)的Roles和Users屬性。

驗證配置文件的方法如下:

  private bool ValidateAuthorizeConfig(Principal principal, AuthorizationContext context)

  {

    //action可能有重載,重載時應(yīng)該標(biāo)記ActionName區(qū)分

    ActionNameAttribute actionNameAttr = context.ActionDescriptor

      .GetCustomAttributes(typeof(ActionNameAttribute), false)

      .OfType<ActionNameAttribute>().FirstOrDefault();

    string actionName = actionNameAttr == null ? null : actionNameAttr.Name;

    AuthorizationConfig ac = ParseAuthorizeConfig(actionName, context.RouteData);

    if (ac != null)

    {

      if (!principal.IsInRole(ac.Roles))

      {

        return false;

      }

      if (!principal.IsInUser(ac.Users))

      {

        return false;

      }

    }

    return true;

  }

  private AuthorizationConfig ParseAuthorizeConfig(string actionName, RouteData routeData)

  {

    string areaName = routeData.DataTokens["area"] as string;

    string controllerName = null;

    object controller, action;

    if(string.IsNullOrEmpty(actionName))

    {

      if(routeData.Values.TryGetValue("action", out action))

      {

        actionName = action.ToString();

      }

    }

    if (routeData.Values.TryGetValue("controller", out controller))

    {

      controllerName = controller.ToString();

    }

    if(!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName))

    {

      return AuthorizationConfig.ParseAuthorizationConfig(

        areaName, controllerName, actionName);

    }

    return null;

  }

}

可以看到,它會根據(jù)當(dāng)前請求的area、controller和action名稱,通過一個AuthorizationConfig類進(jìn)行驗證,該類的定義如下:

public class AuthorizationConfig

{

  public string Roles { get; set; }

  public string Users { get; set; }

  private static XDocument _doc;

  //配置文件路徑

  private static string _path = "~/Identity/Authorization.xml";

  //首次使用加載配置文件

  static AuthorizationConfig()

  {

    string absPath = HttpContext.Current.Server.MapPath(_path);

    if (File.Exists(absPath))

    {

      _doc = XDocument.Load(absPath);

    }

  }

  //解析配置文件,獲得包含Roles和Users的信息

  public static AuthorizationConfig ParseAuthorizationConfig(string areaName, string controllerName, string actionName)

  {

    EnsureHelper.EnsureNotNullOrEmpty(controllerName, "controllerName");

    EnsureHelper.EnsureNotNullOrEmpty(actionName, "actionName");

    if (_doc == null)

    {

      return null;

    }

    XElement rootElement = _doc.Element("root");

    if (rootElement == null)

    {

      return null;

    }

    AuthorizationConfig info = new AuthorizationConfig();

    XElement rolesElement = null;

    XElement usersElement = null;

    XElement areaElement = rootElement.Elements("area")

      .Where(e => CompareName(e, areaName)).FirstOrDefault();

    XElement targetElement = areaElement ?? rootElement;

    XElement controllerElement = targetElement.Elements("controller")

      .Where(e => CompareName(e, controllerName)).FirstOrDefault();

    //如果沒有area節(jié)點和controller節(jié)點則返回null

    if (areaElement == null && controllerElement == null)

    {

      return null;

    }

    //此時獲取標(biāo)記的area

    if (controllerElement == null)

    {

      rootElement = areaElement.Element("roles");

      usersElement = areaElement.Element("users");

    }

    else

    {

      XElement actionElement = controllerElement.Elements("action")

        .Where(e => CompareName(e, actionName)).FirstOrDefault();

      if (actionElement != null)

      {

        //此時獲取標(biāo)記action的

        rolesElement = actionElement.Element("roles");

        usersElement = actionElement.Element("users");

      }

      else

      {

        //此時獲取標(biāo)記controller的

        rolesElement = controllerElement.Element("roles");

        usersElement = controllerElement.Element("users");

      }

    }

    info.Roles = rolesElement == null ? null : rolesElement.Value;

    info.Users = usersElement == null ? null : usersElement.Value;

    return info;

  }

  private static bool CompareName(XElement e, string value)

  {

    XAttribute attribute = e.Attribute("name");

    if (attribute == null || string.IsNullOrEmpty(attribute.Value))

    {

      return false;

    }

    return attribute.Value.Equals(value, StringComparison.OrdinalIgnoreCase);

  }

}

這里的代碼比較長,但主要邏輯就是解析文章開頭的配置信息。

簡單總結(jié)一下程序?qū)崿F(xiàn)的步驟:

1. 校對用戶名和密碼正確后,調(diào)用SetAuthenticationCookie將一些狀態(tài)信息寫入cookie。

2. 在HttpApplication的Authentication事件中,調(diào)用TryParsePrincipal獲得狀態(tài)信息。

3. 在需要驗證的Action(或Controller)標(biāo)記 RequestAuthorizeAttribute特性,并設(shè)置Roles和Users;Roles和Users也可以在配置文件中配置。

4. 在RequestAuthorizeAttribute的OnAuthorization方法中進(jìn)行驗證和權(quán)限邏輯處理。

四、總結(jié)

上面就是整個登錄認(rèn)證的核心實現(xiàn)過程,只需要簡單配置一下就可以實現(xiàn)了。但實際項目中從用戶注冊到用戶管理整個過程是比較復(fù)雜的,而且涉及到前后端驗證、加解密問題。關(guān)于安全問題,F(xiàn)ormsAuthentication在加密的時候,會根據(jù)服務(wù)器的MachineKey等一些信息進(jìn)行加密,所以相對安全。當(dāng)然,如果說請求被惡意攔截,然后被偽造登錄還是有可能的,這是后面要考慮的問題了,例如使用安全的http協(xié)議https。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。

更多信息請查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機(jī)網(wǎng)站地址:詳解ASP.NET MVC Form表單驗證
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2026上岸·考公考編培訓(xùn)報班

  • 報班類型
  • 姓名
  • 手機(jī)號
  • 驗證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機(jī)站點 | 投訴建議
工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報警專用圖標(biāo)
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
国产精品久久久久久久午夜| 国产精品国产三级国产专区53 | 欧美极品一区二区三区| 欧美福利一区二区| 在线观看欧美亚洲| 免费欧美在线视频| av成人天堂| 欧美天堂亚洲电影院在线观看 | 午夜精品三级视频福利| 国产欧美一区二区视频| 欧美一区二区播放| 国产女主播视频一区二区| 国产亚洲欧美日韩美女| 欧美高清视频一区二区三区在线观看| 国产一区二区无遮挡| 中文在线不卡| 国产婷婷色一区二区三区在线| 亚洲电影激情视频网站| 亚洲欧美日韩视频二区| 国产精品美女诱惑| 亚洲欧美日韩一区二区| 亚洲美女在线观看| 国内自拍一区| 欧美视频在线一区二区三区| 久久精彩视频| 亚洲精品在线免费| 欧美三级日本三级少妇99| 亚洲精品永久免费| 国产精品亚洲一区二区三区在线| 免费日韩视频| 亚洲欧美国产制服动漫| 影音欧美亚洲| 国产欧美精品日韩精品| 国产精品激情电影| 欧美色图一区二区三区| 国产精品视频999| 亚洲午夜黄色| 亚洲免费成人av| 亚洲激情在线观看| 亚洲一区www| 午夜精品久久久久久久久久久久久| 欧美日韩精品在线观看| 国产在线精品一区二区中文| 亚洲视频网在线直播| 久久久噜噜噜久久中文字幕色伊伊| 欧美激情bt| 亚洲精品乱码| 国产精品捆绑调教| 激情六月婷婷久久| 欧美一区午夜精品| 国产亚洲午夜| 欧美高潮视频| 亚洲精品综合精品自拍| 免费在线成人| 99国内精品| 国产精品久久久一区麻豆最新章节| 亚洲一区二区三区久久| 91久久夜色精品国产网站| 久久久国产精彩视频美女艺术照福利| 国产精品二区三区四区| 麻豆国产精品va在线观看不卡| 在线一区二区视频| 亚洲欧洲另类| 91久久精品美女高潮| 亚洲第一福利视频| 欧美日韩精品系列| 亚洲欧美日韩人成在线播放| 国产麻豆综合| 欧美电影免费观看高清| 一区二区三区导航| 韩国av一区二区| 欧美成人免费网| 亚洲私人黄色宅男| 一区二区三区在线看| 欧美精品v国产精品v日韩精品| 亚洲午夜在线| 亚洲丶国产丶欧美一区二区三区 | 国产精品国码视频| 免费在线观看一区二区| 亚洲免费在线视频一区 二区| 在线国产亚洲欧美| 国产精品久久久久久久久动漫| 亚洲欧美久久久| 亚洲精选一区二区| 国产在线精品一区二区中文| 欧美国产精品久久| 久久久久久久一区二区三区| 亚洲美女在线视频| 国产一区二区三区高清播放| 欧美日韩在线观看一区二区三区| 久久视频在线免费观看| 久久精品成人欧美大片古装| 亚洲影院色在线观看免费| 亚洲视频一起| 亚洲在线免费视频| 小处雏高清一区二区三区| 亚洲欧美日韩国产综合| 亚洲欧美日韩网| 欧美综合第一页| 久久九九久精品国产免费直播| 香蕉久久夜色| 久久视频一区| 欧美99久久| 欧美日韩亚洲一区在线观看| 欧美日韩四区| 国产区亚洲区欧美区| 一区二区在线视频| 亚洲激情亚洲| 亚洲一区在线观看免费观看电影高清| 亚洲婷婷综合色高清在线| 欧美一级电影久久| 免费欧美高清视频| 国产精品成人国产乱一区| 国产伊人精品| 亚洲性感美女99在线| 久久免费视频网站| 欧美丝袜第一区| 亚洲丁香婷深爱综合| 亚洲在线观看视频网站| 麻豆精品网站| 国产日韩欧美中文| 日韩小视频在线观看专区| 亚洲免费在线视频一区 二区| 久久精品99无色码中文字幕| 欧美日韩视频在线一区二区 | 久久久欧美精品| 欧美三日本三级三级在线播放| 国产日韩欧美夫妻视频在线观看| 亚洲国产欧美一区二区三区同亚洲| 亚洲无限av看| 欧美另类亚洲| 亚洲人成7777| 久久中文字幕一区| 国产在线乱码一区二区三区| 亚洲私人黄色宅男| 欧美日韩三级一区二区| 亚洲高清av在线| 久久久不卡网国产精品一区| 欧美日韩中文精品| 亚洲免费播放| 欧美激情综合色综合啪啪| 欧美精品日韩一本| 欧美电影免费网站| 国产视频一区在线| 亚洲激情午夜| 久久精视频免费在线久久完整在线看| 欧美性jizz18性欧美| 亚洲精品国产精品国自产在线| 久久综合99re88久久爱| 国产精品亚洲精品| 亚洲欧美在线观看| 国产精品久久久久久久久免费桃花| 亚洲精品视频免费观看| 久久女同精品一区二区| 亚洲高清电影| 欧美福利在线| 国产欧美一区二区三区国产幕精品 | 亚洲欧美网站| 国产精品丝袜久久久久久app| 亚洲欧美日韩国产一区二区三区| 国产精品日韩精品| 久久伊人亚洲| 亚洲一区二区免费| 精品福利免费观看| 欧美日韩在线另类| 午夜精品一区二区三区四区| 亚洲女同性videos| 曰韩精品一区二区| 久久久蜜桃一区二区人| 亚洲高清一区二| 欧美不卡视频一区| 亚洲午夜三级在线| 国产一区二区三区自拍| 蜜臀91精品一区二区三区| 99av国产精品欲麻豆| 国产精品免费久久久久久| 久久久亚洲高清| 亚洲特色特黄| 国产主播一区二区| 欧美激情一级片一区二区| 欧美一区二区三区精品| 亚洲人成网站999久久久综合| 亚洲国产你懂的| 亚洲国产日韩一区二区| 欧美午夜精品一区| 欧美成人a∨高清免费观看| 香蕉久久久久久久av网站| 9l视频自拍蝌蚪9l视频成人| 国产在线成人| 国产一区二区三区av电影| 国产日本欧洲亚洲| 国产精品啊v在线| 欧美日韩在线视频一区| 欧美另类videos死尸| 欧美高清视频在线播放| 欧美好吊妞视频| 欧美精品免费在线观看| 欧美精品国产| 国产精品高清免费在线观看| 欧美性色视频在线|