精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

手把手教你,使用JWT實現單點登錄

開發 前端
JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案之一,今天我們一起來揭開它神秘的面紗!

[[326154]]

JSON Web Token(JWT)是目前最流行的跨域身份驗證解決方案之一,今天我們一起來揭開它神秘的面紗!

一、故事起源

說起 JWT,我們先來談一談基于傳統session認證的方案以及瓶頸。

傳統session交互流程,如下圖:

當瀏覽器向服務器發送登錄請求時,驗證通過之后,會將用戶信息存入seesion中,然后服務器會生成一個sessionId放入cookie中,隨后返回給瀏覽器。

當瀏覽器再次發送請求時,會在請求頭部的cookie中放入sessionId,將請求數據一并發送給服務器。

服務器就可以再次從seesion獲取用戶信息,整個流程完畢!

通常在服務端會設置seesion的時長,例如 30 分鐘沒有活動,會將已經存放的用戶信息從seesion中移除。

  1. session.setMaxInactiveInterval(30 * 60);//30分鐘沒活動,自動移除 

同時,在服務端也可以通過seesion來判斷當前用戶是否已經登錄,如果為空表示沒有登錄,直接跳轉到登錄頁面;如果不為空,可以從session中獲取用戶信息即可進行后續操作。

在單體應用中,這樣的交互方式,是沒啥問題的。

但是,假如應用服務器的請求量變得很大,而單臺服務器能支撐的請求量是有限的,這個時候就容易出現請求變慢或者OOM。

解決的辦法,要么給單臺服務器增加配置,要么增加新的服務器,通過負載均衡來滿足業務的需求。

如果是給單臺服務器增加配置,請求量繼續變大,依然無法支撐業務處理。

顯而易見,增加新的服務器,可以實現無限的水平擴展。

但是增加新的服務器之后,不同的服務器之間的sessionId是不一樣的,可能在A服務器上已經登錄成功了,能從服務器的session中獲取用戶信息,但是在B服務器上卻查不到session信息,此時肯定無比的尷尬,只好退出來繼續登錄,結果A服務器中的session因為超時失效,登錄之后又被強制退出來要求重新登錄,想想都挺尷尬~~

面對這種情況,幾位大佬于是合起來商議,想出了一個token方案。

將各個應用程序與內存數據庫redis相連,對登錄成功的用戶信息進行一定的算法加密,生成的ID被稱為token,將token還有用戶的信息存入redis;等用戶再次發起請求的時候,將token還有請求數據一并發送給服務器,服務端驗證token是否存在redis中,如果存在,表示驗證通過,如果不存在,告訴瀏覽器跳轉到登錄頁面,流程結束。

token方案保證了服務的無狀態,所有的信息都是存在分布式緩存中。基于分布式存儲,這樣可以水平擴展來支持高并發。

當然,現在springboot還提供了session共享方案,類似token方案將session存入到redis中,在集群環境下實現一次登錄之后,每個服務器都可以獲取到用戶信息。

二、JWT是什么

上文中,我們談到的session還有token的方案,在集群環境下,他們都是靠第三方緩存數據庫redis來實現數據的共享。

那有沒有一種方案,不用緩存數據庫redis來實現用戶信息的共享,以達到一次登錄,處處可見的效果呢?

答案肯定是有的,就是我們今天要介紹的JWT!

JWT全稱JSON Web Token,實現過程簡單的說就是用戶登錄成功之后,將用戶的信息進行加密,然后生成一個token返回給客戶端,與傳統的session交互沒太大區別。

交互流程如下:

唯一的不同點就是:token存放了用戶的基本信息,更直觀一點就是將原本放入redis中的用戶數據,放入到token中去了!

這樣一來,客戶端、服務端都可以從token中獲取用戶的基本信息,既然客戶端可以獲取,肯定是不能存放敏感信息的,因為瀏覽器可以直接從token獲取用戶信息。

JWT具體長什么樣呢?

JWT是由三段信息構成的,將這三段信息文本用.鏈接一起就構成了JWT字符串。就像這樣:

  1. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 
  • 第一部分:我們稱它為頭部(header),用于存放token類型和加密協議,一般都是固定的;
  • 第二部分:我們稱其為載荷(payload),用戶數據就存放在里面;
  • 第三部分:是簽證(signature),主要用于服務端的驗證;

1、header

JWT的頭部承載兩部分信息:

  • 聲明類型,這里是JWT;
  • 聲明加密的算法,通常直接使用 HMAC SHA256;

完整的頭部就像下面這樣的JSON:

  1.   'typ''JWT'
  2.   'alg''HS256' 

使用base64加密,構成了第一部分。

  1. eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 

2、playload

載荷就是存放有效信息的地方,這些有效信息包含三個部分:

  • 標準中注冊的聲明;
  • 公共的聲明;
  • 私有的聲明;

其中,標準中注冊的聲明 (建議但不強制使用)包括如下幾個部分 :

  • iss: jwt簽發者;
  • sub: jwt所面向的用戶;
  • aud: 接收jwt的一方;
  • exp: jwt的過期時間,這個過期時間必須要大于簽發時間;
  • nbf: 定義在什么時間之前,該jwt都是不可用的;
  • iat: jwt的簽發時間;
  • jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊;

公共的聲明部分:公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息,但不建議添加敏感信息,因為該部分在客戶端可解密。

私有的聲明部分:私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。

定義一個payload:

  1.   "sub""1234567890"
  2.   "name""John Doe"
  3.   "admin"true 

然后將其進行base64加密,得到Jwt的第二部分:

  1. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9 

3、signature

jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:

  • header (base64后的);
  • payload (base64后的);
  • secret (密鑰);

這個部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串,然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構成了jwt的第三部分。

  1. //javascript 
  2. var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); 
  3.  
  4. var signature = HMACSHA256(encodedString, '密鑰'); 

加密之后,得到signature簽名信息。

  1. TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

將這三部分用.連接成一個完整的字符串,就構成了最終的jwt:

  1. //jwt最終格式 
  2. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 

這個只是通過javascript實現的一個演示,JWT的簽發和密鑰的保存都是在服務端來完成。

secret用來進行jwt的簽發和jwt的驗證,所以,在任何場景都不應該流露出去。

三、實戰

介紹了這么多,怎么實現呢?廢話不多說,下面我們直接開擼!

  • 創建一個springboot項目,添加JWT依賴庫
  1. <!-- jwt支持 --> 
  2. <dependency> 
  3.     <groupId>com.auth0</groupId> 
  4.     <artifactId>java-jwt</artifactId> 
  5.     <version>3.4.0</version> 
  6. </dependency> 

 

  • 然后,創建一個用戶信息類,將會通過加密存放在token中
  1. @Data 
  2. @EqualsAndHashCode(callSuper = false
  3. @Accessors(chain = true
  4. public class UserToken implements Serializable { 
  5.  
  6.     private static final long serialVersionUID = 1L; 
  7.  
  8.     /** 
  9.      * 用戶ID 
  10.      */ 
  11.     private String userId; 
  12.  
  13.     /** 
  14.      * 用戶登錄賬戶 
  15.      */ 
  16.     private String userNo; 
  17.  
  18.     /** 
  19.      * 用戶中文名 
  20.      */ 
  21.     private String userName; 
  • 接著,創建一個JwtTokenUtil工具類,用于創建token、驗證token
  1. public class JwtTokenUtil { 
  2.  
  3.     //定義token返回頭部 
  4.     public static final String AUTH_HEADER_KEY = "Authorization"
  5.  
  6.     //token前綴 
  7.     public static final String TOKEN_PREFIX = "Bearer "
  8.  
  9.     //簽名密鑰 
  10.     public static final String KEY = "q3t6w9z$C&F)J@NcQfTjWnZr4u7x"
  11.      
  12.     //有效期默認為 2hour 
  13.     public static final Long EXPIRATION_TIME = 1000L*60*60*2; 
  14.  
  15.  
  16.     /** 
  17.      * 創建TOKEN 
  18.      * @param content 
  19.      * @return 
  20.      */ 
  21.     public static String createToken(String content){ 
  22.         return TOKEN_PREFIX + JWT.create() 
  23.                 .withSubject(content) 
  24.                 .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) 
  25.                 .sign(Algorithm.HMAC512(KEY)); 
  26.     } 
  27.  
  28.     /** 
  29.      * 驗證token 
  30.      * @param token 
  31.      */ 
  32.     public static String verifyToken(String token) throws Exception { 
  33.         try { 
  34.             return JWT.require(Algorithm.HMAC512(KEY)) 
  35.                     .build() 
  36.                     .verify(token.replace(TOKEN_PREFIX, "")) 
  37.                     .getSubject(); 
  38.         } catch (TokenExpiredException e){ 
  39.             throw new Exception("token已失效,請重新登錄",e); 
  40.         } catch (JWTVerificationException e) { 
  41.             throw new Exception("token驗證失敗!",e); 
  42.         } 
  43.     } 
  • 編寫配置類,允許跨域,并且創建一個權限攔截器
  1. @Slf4j 
  2. @Configuration 
  3. public class GlobalWebMvcConfig implements WebMvcConfigurer { 
  4.        /** 
  5.      * 重寫父類提供的跨域請求處理的接口 
  6.      * @param registry 
  7.      */ 
  8.     @Override 
  9.     public void addCorsMappings(CorsRegistry registry) { 
  10.         // 添加映射路徑 
  11.         registry.addMapping("/**"
  12.                 // 放行哪些原始域 
  13.                 .allowedOrigins("*"
  14.                 // 是否發送Cookie信息 
  15.                 .allowCredentials(true
  16.                 // 放行哪些原始域(請求方式) 
  17.                 .allowedMethods("GET""POST""DELETE""PUT""OPTIONS""HEAD"
  18.                 // 放行哪些原始域(頭部信息) 
  19.                 .allowedHeaders("*"
  20.                 // 暴露哪些頭部信息(因為跨域訪問默認不能獲取全部頭部信息) 
  21.                 .exposedHeaders("Server","Content-Length""Authorization""Access-Token""Access-Control-Allow-Origin","Access-Control-Allow-Credentials"); 
  22.     } 
  23.  
  24.     /** 
  25.      * 添加攔截器 
  26.      * @param registry 
  27.      */ 
  28.     @Override 
  29.     public void addInterceptors(InterceptorRegistry registry) { 
  30.         //添加權限攔截器 
  31.         registry.addInterceptor(new AuthenticationInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**"); 
  32.     } 
  • 使用AuthenticationInterceptor攔截器對接口參數進行驗證
  1. @Slf4j 
  2. public class AuthenticationInterceptor implements HandlerInterceptor { 
  3.  
  4.     @Override 
  5.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
  6.         // 從http請求頭中取出token 
  7.         final String token = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY); 
  8.         //如果不是映射到方法,直接通過 
  9.         if(!(handler instanceof HandlerMethod)){ 
  10.             return true
  11.         } 
  12.         //如果是方法探測,直接通過 
  13.         if (HttpMethod.OPTIONS.equals(request.getMethod())) { 
  14.             response.setStatus(HttpServletResponse.SC_OK); 
  15.             return true
  16.         } 
  17.         //如果方法有JwtIgnore注解,直接通過 
  18.         HandlerMethod handlerMethod = (HandlerMethod) handler; 
  19.         Method method=handlerMethod.getMethod(); 
  20.         if (method.isAnnotationPresent(JwtIgnore.class)) { 
  21.             JwtIgnore jwtIgnore = method.getAnnotation(JwtIgnore.class); 
  22.             if(jwtIgnore.value()){ 
  23.                 return true
  24.             } 
  25.         } 
  26.         LocalAssert.isStringEmpty(token, "token為空,鑒權失敗!"); 
  27.         //驗證,并獲取token內部信息 
  28.         String userToken = JwtTokenUtil.verifyToken(token); 
  29.          
  30.         //將token放入本地緩存 
  31.         WebContextUtil.setUserToken(userToken); 
  32.         return true
  33.     } 
  34.  
  35.     @Override 
  36.     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 
  37.         //方法結束后,移除緩存的token 
  38.         WebContextUtil.removeUserToken(); 
  39.     } 
  • 最后,在controller層用戶登錄之后,創建一個token,存放在頭部即可
  1. /** 
  2.  * 登錄 
  3.  * @param userDto 
  4.  * @return 
  5.  */ 
  6. @JwtIgnore 
  7. @RequestMapping(value = "/login", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) 
  8. public UserVo login(@RequestBody UserDto userDto, HttpServletResponse response){ 
  9.     //...參數合法性驗證 
  10.  
  11.     //從數據庫獲取用戶信息 
  12.     User dbUser = userService.selectByUserNo(userDto.getUserNo); 
  13.  
  14.     //....用戶、密碼驗證 
  15.  
  16.     //創建token,并將token放在響應頭 
  17.     UserToken userToken = new UserToken(); 
  18.     BeanUtils.copyProperties(dbUser,userToken); 
  19.  
  20.     String token = JwtTokenUtil.createToken(JSONObject.toJSONString(userToken)); 
  21.     response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, token); 
  22.  
  23.  
  24.     //定義返回結果 
  25.     UserVo result = new UserVo(); 
  26.     BeanUtils.copyProperties(dbUser,result); 
  27.     return result; 

到這里基本就完成了!

其中AuthenticationInterceptor中用到的JwtIgnore是一個注解,用于不需要驗證token的方法上,例如驗證碼的獲取等等。

  1. @Target({ElementType.METHOD, ElementType.TYPE}) 
  2. @Retention(RetentionPolicy.RUNTIME) 
  3. public @interface JwtIgnore { 
  4.  
  5.     boolean value() default true

而WebContextUtil是一個線程緩存工具類,其他接口通過這個方法即可從token中獲取用戶信息。

  1. public class WebContextUtil { 
  2.  
  3.     //本地線程緩存token 
  4.     private static ThreadLocal<String> local = new ThreadLocal<>(); 
  5.  
  6.     /** 
  7.      * 設置token信息 
  8.      * @param content 
  9.      */ 
  10.     public static void setUserToken(String content){ 
  11.         removeUserToken(); 
  12.         local.set(content); 
  13.     } 
  14.  
  15.     /** 
  16.      * 獲取token信息 
  17.      * @return 
  18.      */ 
  19.     public static UserToken getUserToken(){ 
  20.         if(local.get() != null){ 
  21.             UserToken userToken = JSONObject.parseObject(local.get() , UserToken.class); 
  22.             return userToken; 
  23.         } 
  24.         return null
  25.     } 
  26.  
  27.     /** 
  28.      * 移除token信息 
  29.      * @return 
  30.      */ 
  31.     public static void removeUserToken(){ 
  32.         if(local.get() != null){ 
  33.             local.remove(); 
  34.         } 
  35.     } 

最后,啟動項目,我們來用postman測試一下,看看頭部返回結果。

我們把返回的信息提取處理,使用瀏覽器的base64對前兩個部分進行解密。

  • 第一部分,也就是header,結果如下:
  • 第二部分,也就是playload,結果如下:

可以很清晰的看到,頭部、載荷的信息都可以通過base64解密出來。

所以,一定別在token中存放敏感信息!

當我們需要請求其它服務接口時,只需要在請求頭部headers中加入Authorization參數即可。

當權限攔截器驗證通過之后,在接口方法中只需要通過WebContextUtil工具類就可以獲取用戶信息。

  1. //獲取用戶token信息 
  2. UserToken userToken = WebContextUtil.getUserToken(); 

四、總結

JWT相比session方案,因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA、JavaScript、PHP等很多語言都可以使用,而session方案只針對JAVA。

因為有了payload部分,所以JWT可以存儲一些其他業務邏輯所必要的非敏感信息。

同時,保護好服務端secret私鑰非常重要,因為私鑰可以對數據進行驗證、解密!

如果可以,請使用https協議!

五、參考

1、簡書 - 什么是 JWT -- JSON WEB TOKEN

 

2、博客園 - 基于session和token的身份認證方案

 

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2021-06-29 12:27:19

Spring BootCAS 登錄

2021-07-14 09:00:00

JavaFX開發應用

2025-05-07 00:31:30

2023-04-26 12:46:43

DockerSpringKubernetes

2021-03-12 10:01:24

JavaScript 前端表單驗證

2022-12-07 08:42:35

2009-11-09 14:57:37

WCF上傳文件

2011-01-06 10:39:25

.NET程序打包

2021-08-02 07:35:19

Nacos配置中心namespace

2011-05-03 15:59:00

黑盒打印機

2011-01-10 14:41:26

2021-04-02 10:01:00

JavaScript前端Web項目

2025-01-13 09:07:12

2011-04-21 10:32:44

MySQL雙機同步

2021-01-19 09:06:21

MysqlDjango數據庫

2022-07-22 12:45:39

GNU

2022-10-30 10:31:42

i2ccpuftrace

2021-12-15 08:49:21

gpio 子系統pinctrl 子系統API

2022-01-08 20:04:20

攔截系統調用

2022-03-14 14:47:21

HarmonyOS操作系統鴻蒙
點贊
收藏

51CTO技術棧公眾號

亚洲色图视频网| 欧美成人日韩| 欧美在线不卡一区| 亚洲免费在线精品一区| 亚洲在线免费观看视频| 好看的日韩av电影| 国产亚洲欧美日韩美女| 亚洲熟女乱综合一区二区| 不卡av播放| 亚洲女与黑人做爰| 麻豆亚洲一区| 久草视频国产在线| 欧美在线aaa| 日本a级在线| av在线播放成人| 成人在线中文字幕| 青青青国产在线| 欧美伊人久久| 夜夜嗨av色一区二区不卡| 亚洲一级片免费观看| 欧美色网在线| 午夜私人影院久久久久| 三年中国中文在线观看免费播放| 日韩偷拍自拍| 高清成人在线观看| 成人免费xxxxx在线观看| 天天综合网久久综合网| 国产精品videossex久久发布| 中日韩美女免费视频网址在线观看| 黄色性视频网站| 免费一区二区三区在线视频| 欧美日韩一二区| 国产成人手机视频| 僵尸再翻生在线观看免费国语| 亚洲码国产岛国毛片在线| 蜜桃视频在线观看成人| 人妻少妇精品无码专区久久| 国产一区二区三区久久久| 国产精品一区电影| 日韩不卡高清视频| 玖玖在线精品| 青青青国产精品一区二区| 日韩久久久久久久久| 韩日视频一区| 欧美华人在线视频| 久草网在线观看| 午夜精品久久99蜜桃的功能介绍| 久久视频在线免费观看| 中国一级片在线观看| 三上亚洲一区二区| 亚洲精品国产成人久久av盗摄| 日韩欧美国产一区二区三区 | 亚洲欧洲另类| 欧美国产一区二区三区| 青青青在线免费观看| 天天做天天爱天天综合网| 日韩在线观看成人| 日韩在线视频网址| 综合一区二区三区| 欧美高清激情视频| 国产一级做a爰片在线看免费| 欧美日本不卡| 97精品国产aⅴ7777| 亚洲精品1区2区3区| 午夜在线一区二区| 国产成一区二区| 一级黄色片在线播放| 久久99国产精品久久99果冻传媒| 国产中文字幕亚洲| 国产不卡av在线播放| 处破女av一区二区| 六月婷婷久久| 丝袜美腿美女被狂躁在线观看 | 日韩黄色三级视频| 老鸭窝亚洲一区二区三区| 国产精品r级在线| 一级α片免费看刺激高潮视频| 极品少妇一区二区| 国产精品毛片va一区二区三区| 先锋av资源站| 国产精品全国免费观看高清| 午夜久久久久久久久久久| 97天天综合网| 在线精品亚洲一区二区不卡| 午夜国产福利在线观看| 成人av动漫| 亚洲无限av看| 麻豆chinese极品少妇| 国产精品美女| 91精品国产自产在线观看永久| 亚洲精品成人区在线观看| 久久综合视频网| 中文字幕欧美人与畜| jizz一区二区三区| 欧美午夜精品免费| 黑人玩弄人妻一区二区三区| 国产一区二区三区四区大秀| 欧美成人高清视频| 国产成人精品777777| 经典一区二区三区| 欧美午夜免费| 影音先锋中文在线视频| 日本精品视频一区二区| 韩国一区二区三区四区| 九九久久精品| 欧美韩国理论所午夜片917电影| 亚洲天堂一区在线| 国产乱人伦偷精品视频不卡| 欧美日韩精品久久| 欧美理论电影| 欧美日韩国产高清一区| 97香蕉碰碰人妻国产欧美| 婷婷久久一区| 国产精品久久久久久久av电影| 亚洲国产精品成人久久蜜臀| 国产精品无遮挡| 日韩av一二三四区| 综合中文字幕| 日韩色av导航| 青娱乐在线免费视频| av男人天堂一区| 激情五月六月婷婷| 欧美黄页免费| 在线视频国产日韩| 综合激情网五月| 成人小视频在线| 国产成人免费高清视频| 国产a亚洲精品| 国产一区二区久久精品| 毛片在线免费视频| 白白色 亚洲乱淫| 成人免费在线视频播放| 91精品国产色综合久久不卡粉嫩| 亚洲一区二区久久久| 一区二区三区在线观看av| 成人18视频在线播放| www.在线观看av| 国产人与zoxxxx另类91| 久久精品国产69国产精品亚洲| 国产字幕在线观看| 久久久国产综合精品女国产盗摄| 国产成人无码精品久久久性色| heyzo欧美激情| 欧美激情一区二区三区在线视频观看 | 国产污视频在线| 一本色道久久综合亚洲aⅴ蜜桃| 男人网站在线观看| 伊人激情综合| 国产日韩一区欧美| 国产在线88av| 精品网站999www| 伊人中文字幕在线观看| 久久久久久97三级| 一级特黄性色生活片| 国产成人一区| 国产精品视频免费观看www| jizz亚洲| 91精品国产综合久久精品性色| 青青操在线视频观看| 九色综合国产一区二区三区| 性生活免费观看视频| 日韩免费高清视频网站| 久久久久久久久网站| 午夜成人免费影院| 91福利国产精品| 欧美性生给视频| 成人性视频免费网站| 黄页网站在线观看视频| 午夜a一级毛片亚洲欧洲| 国产成人免费av电影| 色老头视频在线观看| 日韩三级在线免费观看| 国产极品美女高潮无套嗷嗷叫酒店| 成人小视频在线| 国产激情在线观看视频| 外国成人激情视频| 国产成人精品免费视频大全最热| 福利在线免费视频| 亚洲香蕉成视频在线观看| 亚洲天堂国产精品| 亚洲一区免费视频| av电影在线不卡| 国模大尺度一区二区三区| 欧美国产视频一区| 欧美美女在线观看| 亚洲淫片在线视频| 天天综合av| 蜜臀久久99精品久久久无需会员 | 在线视频亚洲欧美| 亚洲黄色a级片| 色狠狠一区二区三区香蕉| а天堂中文在线资源| 99久久精品国产精品久久 | 成人午夜视频网站| 国产偷人视频免费| 一区二区三区四区电影| 欧美凹凸一区二区三区视频| 97久久精品一区二区三区的观看方式| 97人人爽人人喊人人模波多| 黄网站免费在线观看| 日韩精品电影网| a级片免费视频| 欧美综合亚洲图片综合区| 久久久久无码国产精品不卡| 中文在线一区二区| 欧美一区二区免费在线观看| 精品一区中文字幕| 99视频在线免费| 亚洲欧洲一区二区天堂久久| 国产又黄又爽免费视频| 一个色免费成人影院| 99re在线国产| 国产精品一区二区免费福利视频| 91av在线免费观看视频| 色呦呦呦在线观看| 久久手机精品视频| av国产在线观看| 亚洲男人天堂视频| 乱精品一区字幕二区| 91精品国产全国免费观看| 国产91av在线播放| 色哟哟亚洲精品| 日韩免费观看一区二区| 一区二区三区资源| 黄色香蕉视频在线观看| 国产欧美一区二区精品性色| 国产麻豆天美果冻无码视频 | 性欧美猛交videos| 上原亚衣av一区二区三区| 青青青免费视频在线2| 亚洲白虎美女被爆操| av在线亚洲天堂| 在线成人免费视频| 一级做a爱片性色毛片| 色哟哟一区二区| 亚洲av无码精品一区二区| 狠狠色噜噜狠狠狠狠97| 男女视频免费看| 午夜av一区二区| 欧美一级视频免费观看| 亚洲第一搞黄网站| 国产精品第56页| 亚洲成人午夜影院| 香蕉免费毛片视频| 五月婷婷激情综合| 日韩精品久久久久久久| 欧美日韩国产麻豆| 久久99国产综合精品免费| 日韩欧美高清在线视频| 草久视频在线观看| 色婷婷久久久亚洲一区二区三区| 伊人手机在线视频| 色噜噜狠狠成人网p站| 日韩电影在线观看一区二区| 欧洲生活片亚洲生活在线观看| 成人av网站在线播放| 欧美伊人久久久久久久久影院| 日本成人一级片| 欧美久久久久久久久| 精品久久久久成人码免费动漫| 日韩一二在线观看| 色婷婷av一区二区三| 精品亚洲一区二区三区| 国产精品久久一区二区三区不卡| 少妇激情综合网| 最新av在线播放| 高清一区二区三区日本久| 99riav视频在线观看| 欧美在线视频网站| 九七电影院97理论片久久tvb| 成人动漫网站在线观看| 91精品久久久久久综合五月天| 国产一区二区免费在线观看| 国产午夜一区| 青青草免费在线视频观看| 在线观看日韩av电影| 免费观看成人网| 国产真实乱对白精彩久久| 中国xxxx性xxxx产国| 国产欧美一区二区三区鸳鸯浴| 国产大片免费看| 欧美色videos| 国产乱叫456在线| 亚洲丁香久久久| bbbbbbbbbbb在线视频| 欧美成人免费va影院高清| 天堂中文在线播放| 91免费国产网站| 亚洲天堂日韩在线| 强开小嫩苞一区二区三区网站| 亚洲三级视频| 免费av不卡在线| 91热门视频在线观看| 国产午夜精品理论片| 欧美视频13p| 国产sm主人调教女m视频| 亚洲欧美精品中文字幕在线| av网站在线免费看推荐| 日韩美女在线观看一区| 欧美国产中文高清| 日韩欧美视频一区二区三区四区 | 国产精品久久久久久久裸模| 国产性70yerg老太| 欧美日韩视频专区在线播放| 手机看片国产1024| 久久不射电影网| 欧美影视资讯| 欧美激情专区| 欧美视频一区| 国产乱女淫av麻豆国产| 99久久99久久综合| 欧美被狂躁喷白浆精品| 欧美性色综合网| 日韩专区一区二区| 午夜精品视频在线| 日韩精品一区国产| 99热这里只有精品7| 日韩高清中文字幕一区| 国产乱了高清露脸对白| 亚洲激情中文1区| 亚洲在线免费观看视频| 亚洲性xxxx| 亚洲欧美韩国| 九九九九九精品| 午夜精品电影| 亚洲午夜精品在线观看| 日韩理论片网站| 一起草av在线| 社区色欧美激情 | 欧美亚洲综合视频| 天天久久人人| 蜜臀久久久99精品久久久久久| 女尊高h男高潮呻吟| 欧美视频在线免费| 亚洲av电影一区| 91av成人在线| 亚洲va久久久噜噜噜久久| 国产a级片网站| 99久久精品免费| 一区二区三区福利视频| 国产视频亚洲精品| 亚洲天堂资源| 日本成人黄色免费看| 日韩国产欧美视频| 懂色av粉嫩av浪潮av| 欧美日韩一级黄| 国产激情在线观看| 91手机在线播放| 黄色成人在线网址| 999精品免费视频| 福利一区视频在线观看| 欧美在线观看在线观看| 欧美综合在线观看| 国产一区二区三区四区| 校园春色 亚洲色图| 亚洲欧美影音先锋| 精品国产av一区二区三区| 久久99精品久久久久久青青91| 综合成人在线| 亚洲国产精品久久久久爰色欲| 91麻豆免费观看| 国产情侣免费视频| 欧美成人精品在线播放| 97色成人综合网站| 激情六月丁香婷婷| 亚洲国产精品av| 国产高清免费在线观看| 欧美成人午夜激情| 牛牛影视久久网| 一区二区三区视频在线观看免费| 国产精品久久久久影院| 性做久久久久久久| 欧美专区中文字幕| 五月久久久综合一区二区小说| 国产chinesehd精品露脸| 色先锋久久av资源部| 色网站在线看| 精品国产一区二区三区日日嗨| 天堂影院一区二区| 日日噜噜夜夜狠狠久久波多野| 亚洲成人三级在线| yy6080久久伦理一区二区| 欧美日韩激情四射| 国产夜色精品一区二区av| 99久久精品国产一区色| 7777免费精品视频| 天天色天天射综合网| 朝桐光av一区二区三区| 欧美日韩一区二区三区在线看 | 日本一级大毛片a一| 色系网站成人免费| 手机在线免费av| 欧美连裤袜在线视频| 国产乱码精品一区二区三| 久久青青草原亚洲av无码麻豆| 久久亚洲精品成人| 九九久久婷婷| 亚洲啪av永久无码精品放毛片 | 男人的天堂免费| 欧美在线一二三|