<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      # 第三章 app端用戶認證

      目標

      • 能夠完成網關統一鑒權的功能

      • 能夠完成認證用戶列表查詢

      • 能夠熟悉app端用戶認證審核流程

      • 能夠完成app用戶審核代碼開發

      1 網關校驗jwt

      1.1 微服務網關概述

      不同的微服務一般會有不同的網絡地址,而外部客戶端可能需要調用多個服務的接口才能完成一個業務需求,如果讓客戶端直接與各個微服務通信,會有以下的問題:

      • 客戶端會多次請求不同的微服務,增加了客戶端的復雜性
      • 存在跨域請求,在一定場景下處理相對復雜
      • 認證復雜,每個服務都需要獨立認證
      • 難以重構,隨著項目的迭代,可能需要重新劃分微服務。例如,可能將多個服務合并成一個或者將一個服務拆分成多個。如果客戶端直接與微服務通信,那么重構將會很難實施
      • 某些微服務可能使用了防火墻 / 瀏覽器不友好的協議,直接訪問會有一定的困難

      以上這些問題可以借助網關解決。

      網關是介于客戶端和服務器端之間的中間層,所有的外部請求都會先經過 網關這一層。也就是說,API 的實現方面更多的考慮業務邏輯,而安全、性能、監控可以交由 網關來做,這樣既提高業務靈活性又不缺安全性,典型的架構圖如圖所示:

      1585846768368

      優點如下:

      • 安全 ,只有網關系統對外進行暴露,微服務可以隱藏在內網,通過防火墻保護。
      • 易于監控。可以在網關收集監控數據并將其推送到外部系統進行分析。
      • 易于認證。可以在網關上進行認證,然后再將請求轉發到后端的微服務,而無須在每個微服務中進行認證。
      • 減少了客戶端與各個微服務之間的交互次數
      • 易于統一授權。

      總結:微服務網關就是一個系統,通過暴露該微服務網關系統,方便我們進行相關的鑒權,安全控制,日志統一處理,易于監控的相關功能。

      實現微服務網關的技術有很多,

      • nginx Nginx (engine x) 是一個高性能的HTTP反向代理web服務器,同時也提供了IMAP/POP3/SMTP服務
      • zuul ,Zuul 是 Netflix 出品的一個基于 JVM 路由和服務端的負載均衡器。
      • spring-cloud-gateway, 是spring 出品的 基于spring 的網關項目,集成斷路器,路徑重寫,性能比Zuul好。

      我們使用gateway這個網關技術,無縫銜接到基于spring cloud的微服務開發中來。

      gateway官網:

      https://spring.io/projects/spring-cloud-gateway

      1.2 搭建gatway網關微服務

      (1)創建itheima-leadnews-gateway-admin微服務

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>itheima-leadnews-gateway</artifactId>
              <groupId>com.itheima</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>itheima-leadnews-gateway-admin</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-gateway</artifactId>
              </dependency>
              <dependency>
                  <groupId>com.alibaba.cloud</groupId>
                  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
              </dependency>
               <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-common</artifactId>
                  <version>1.0-SNAPSHOT</version>
                  <exclusions>
                      <exclusion>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </exclusion>
                  </exclusions>
              </dependency>
          </dependencies>
      </project>
      

      1614046040247

      啟動類:

      package com.itheima;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/2/23 10:21
       * @description 標題
       * @package com.itheima
       */
      @SpringBootApplication
      @EnableDiscoveryClient
      public class GatewayAdminApplication {
          public static void main(String[] args) {
              SpringApplication.run(GatewayAdminApplication.class,args);
          }
      }
      
      

      application.yml

      spring:
        profiles:
          active: dev
      ---
      server:
        port: 6001
      spring:
        application:
          name: leadnews-admin-gateway
        profiles: dev
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
          gateway:
            globalcors:
              cors-configurations:
                '[/**]': # 匹配所有請求
                  allowedOrigins: "*" #跨域處理 允許所有的域
                  allowedHeaders: "*"
                  allowedMethods: # 支持的方法
                    - GET
                    - POST
                    - PUT
                    - DELETE
            routes:
              # 平臺管理
              - id: admin
                uri: lb://leadnews-admin
                predicates:
                  - Path=/admin/**
                filters:
                  - StripPrefix= 1
      ---
      server:
        port: 6001
      spring:
        application:
          name: leadnews-admin-gateway
        profiles: test
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
          gateway:
            globalcors:
              cors-configurations:
                '[/**]': # 匹配所有請求
                  allowedOrigins: "*" #跨域處理 允許所有的域
                  allowedHeaders: "*"
                  allowedMethods: # 支持的方法
                    - GET
                    - POST
                    - PUT
                    - DELETE
            routes:
              # 平臺管理
              - id: admin
                uri: lb://leadnews-admin
                predicates:
                  - Path=/admin/**
                filters:
                  - StripPrefix= 1
      ---
      server:
        port: 6001
      spring:
        application:
          name: leadnews-admin-gateway
        profiles: pro
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
          gateway:
            globalcors:
              cors-configurations:
                '[/**]': # 匹配所有請求
                  allowedOrigins: "*" #跨域處理 允許所有的域
                  allowedHeaders: "*"
                  allowedMethods: # 支持的方法
                    - GET
                    - POST
                    - PUT
                    - DELETE
            routes:
              # 平臺管理
              - id: admin
                uri: lb://leadnews-admin
                predicates:
                  - Path=/admin/**
                filters:
                  - StripPrefix= 1
      

      重點解釋:

      - Path=/admin/**  表示以/admin開頭的路徑全部路由到admin微服務中
      例如:http://localhost:6001/admin/xxx/yyy --->路由到http://9001/xxx/yyy
      

      1.3 全局過濾器實現jwt校驗

      有了網關之后,我們應當從網關開始訪問,并通過網關實現權限校驗等功能,結構圖和流程圖如下

      1614048743302

      思路分析:

      1. 用戶進入網關開始登陸,網關過濾器進行判斷,如果是登錄,則路由到后臺管理微服務進行登錄
      2. 用戶登錄成功,后臺管理微服務簽發JWT TOKEN信息返回給用戶
      3. 用戶再次進入網關開始訪問,網關過濾器接收用戶攜帶的TOKEN
      4. 網關過濾器解析TOKEN ,判斷是否有權限,如果有,則放行,如果沒有則返回未認證錯誤

      在網關微服務中新建全局過濾器:

      (1)編寫全局過濾器

      package com.itheima.gatewayadmin.filter;
      
      import com.itheima.common.constants.SystemConstants;
      import com.itheima.common.util.AppJwtUtil;
      import org.checkerframework.checker.units.qual.A;
      import org.springframework.cloud.gateway.filter.GatewayFilterChain;
      import org.springframework.cloud.gateway.filter.GlobalFilter;
      import org.springframework.core.Ordered;
      import org.springframework.http.HttpStatus;
      import org.springframework.http.server.reactive.ServerHttpRequest;
      import org.springframework.http.server.reactive.ServerHttpResponse;
      import org.springframework.stereotype.Component;
      import org.springframework.util.StringUtils;
      import org.springframework.web.server.ServerWebExchange;
      import reactor.core.publisher.Mono;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/8/1 09:06
       * @description 標題
       * @package com.itheima.gatewayadmin.filter
       */
      @Component
      public class AuthorizeFilter implements GlobalFilter, Ordered {
      
          @Override
          public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
              //+ 1.先獲取請求和響應對象
              ServerHttpRequest request = exchange.getRequest();
      
              ServerHttpResponse response = exchange.getResponse();
              // /get /a  post /a
      
              //+ 2.判斷當前的請求 是否 是登錄的請求 如果是 ,則放行
              String path = request.getURI().getPath();
              if(path.startsWith("/admin/admin/login")){
                  return chain.filter(exchange);
              }
      
              //+ 3.獲取頁面傳遞過來的請求頭中的令牌數據 如果獲取不到 返回錯誤(401)
              String token = request.getHeaders().getFirst("token");
              if(StringUtils.isEmpty(token)){
                  response.setStatusCode(HttpStatus.UNAUTHORIZED);
                  return  response.setComplete();//完成響應 返回 后面就不執行了
              }
      
              //+ 4.校驗令牌 校驗失敗 返回錯誤401
              //通過jwt 來校驗
              if(SystemConstants.JWT_OK!=AppJwtUtil.verifyToken(token)){
                  response.setStatusCode(HttpStatus.UNAUTHORIZED);
                  return  response.setComplete();//完成響應 返回 后面就不執行了
              }
              //+ 5.校驗成功 放行
              return chain.filter(exchange);
          }
      
      
          //過濾器的執行的優先級的設置 值越低 優先級越高
          @Override
          public int getOrder() {
              return 0;
          }
      }
      
      

      測試:注意,從網關開始訪問:

      1614048847043

      先登錄:

      1614049027664

      攜帶token再進行訪問:

      1614049110201

      2 APP端用戶實名認流程說明

      2.1 需求分析

      APP端用戶在app端進行實名認證

      1614060639792

      平臺后臺管理系統可以查看實名認證的信息,便于進行審核。

      1614060753555

      當用戶在app前端進行了實名認證請求之后會自動往ap_user_realname表中加入數據

      1605943271408

      我們的需求是:

      需要實現平臺的用戶實名認證的列表信息查詢,如下圖:

      1614060753555

      2.2 搭建user微服務

      (1)新建微服務工程:itheima-leadnews-service-user和對應api工程

      1614069837655

      itheima-leadnews-service-user工程的pom.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>itheima-leadnews-service</artifactId>
              <groupId>com.itheima</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>itheima-leadnews-service-user</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-user-api</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-common-db</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
               <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-core-controller</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
          </dependencies>
      </project>
      

      (2)創建啟動類

      package com.itheima;
      
      import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.context.annotation.Bean;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/2/23 16:45
       * @description 標題
       * @package com.itheima
       */
      @SpringBootApplication
      @EnableDiscoveryClient
      @MapperScan(basePackages = "com.itheima.user.mapper")
      public class UserApplication {
          public static void main(String[] args) {
              SpringApplication.run(UserApplication.class,args);
          }
          @Bean
          public PaginationInterceptor paginationInterceptor() {
              return new PaginationInterceptor();
          }
      }
      

      (3)在resources下新建application.yml

      spring:
        profiles:
          active: dev
      ---
      server:
        port: 9002
      spring:
        application:
          name: leadnews-user
        profiles: dev
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.user.pojo
      ---
      server:
        port: 9002
      spring:
        application:
          name: leadnews-user
        profiles: pro
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.user.pojo
      ---
      server:
        port: 9002
      spring:
        application:
          name: leadnews-user
        profiles: test
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_user?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.user.pojo
      

      (4)使用代碼生成器生成相關的controller service mapper pojo

      1614070188103

      執行生成動作,生成如下:

      1614070346903

      copy代碼到對應工程中,該操作不在文檔中演示了。copy之后查詢的功能就已經實現了。

      此時用戶實名認證列表查詢功能已經完成。啟動服務并測試如下

      1614070765126

      3 app端用戶認證后審核

      3.1 需求分析

      當用戶提交了實名認證之后,認證信息便已經存儲到了數據庫表中。我們平臺需要進行審核。

      審核流程說明如下:

      • 在app端的個人中心用戶可以實名認證,需要材料為:姓名、身份證號、身份證正面照、身份證反面照、手持照片、活體照片(通過微笑、眨眼、張嘴、搖頭、點頭等組合動作,確保操作的為真實活體人臉。),當用戶提交審核后就到了后端讓運營管理人員進行審核
      • 平臺運營端查看用戶認證信息,進行審核,其中審核包括了用戶身份審核,需要對接公安系統校驗身份證信息
      • 用戶通過審核后需要開通自媒體賬號(該賬號的用戶名和密碼與app一致)
      • 用戶通過審核后需要在article中在作者表中新建一個作者信息

      如圖剛才的流程對應的微服務的數據庫為如下圖所示:

      1614071194740

      3.2 實現思路分析

      1614071590563

      上圖解釋:

      1.當平臺管理審核人員進行點擊審核通過的按鈕之后
      2.用戶微服務接收到請求進行數據操作 實名認證狀態
      3.并同時通過Feign調用實現自媒體微服務的業務操作 創建自媒體賬號
      4.并同時通過Feign調用實現文章微服務創建作者信息。
      

      操作步驟說明:

      1.搭建 自媒體微服務 和 文章微服務
      
      2.實現審核通過 用戶微服務 修改狀態
      
      3.創建feign 分別遠程調用 自媒體和文章
      

      4 搭建微服務

      4.1 搭建自媒體微服務

      (1)創建自媒體微服務

      1614072668110

      pom.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>itheima-leadnews-service</artifactId>
              <groupId>com.itheima</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>itheima-leadnews-service-wemedia</artifactId>
          <dependencies>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-common-db</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-wemedia-api</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-core-controller</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
          </dependencies>
      </project>
      

      (2)創建啟動類和yml及相關配置

      package com.itheima;
      
      import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.context.annotation.Bean;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/2/25 15:22
       * @description 標題
       * @package com.itheima
       */
      @SpringBootApplication
      @EnableDiscoveryClient
      @MapperScan(basePackages = "com.itheima.media.mapper")
      public class MediaApplication {
          public static void main(String[] args) {
              SpringApplication.run(MediaApplication.class, args);
          }
          @Bean
          public PaginationInterceptor paginationInterceptor() {
              return new PaginationInterceptor();
          }
      }
      
      

      application.yml

      spring:
        profiles:
          active: dev
      ---
      server:
        port: 9004
      spring:
        profiles: dev
        application:
          name: leadnews-wemedia
        cloud:
          nacos:
            discovery:
              server-addr: 192.168.211.136:8848
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_wemedia?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.media.pojo
      ---
      server:
        port: 9004
      spring:
        profiles: test
        application:
          name: leadnews-wemedia
        cloud:
          nacos:
            discovery:
              server-addr: 192.168.211.136:8848
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_wemedia?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.media.pojo
      ---
      server:
        port: 9004
      spring:
        profiles: pro
        application:
          name: leadnews-wemedia
        cloud:
          nacos:
            discovery:
              server-addr: 192.168.211.136:8848
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_wemedia?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.media.pojo
      

      (3)使用代碼生成器生成相關代碼放到對應位置,copy步驟略,最終效果如下
      1614238372887

      4.2 搭建文章微服務

      (1)創建文章微服務

      1614239135229

      pom.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>itheima-leadnews-service</artifactId>
              <groupId>com.itheima</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>itheima-leadnews-service-article</artifactId>
          <dependencies>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-article-api</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-common-db</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-core-controller</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
          </dependencies>
      </project>
      

      (2)新建啟動類和yaml配置

      package com.itheima;
      
      import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.context.annotation.Bean;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/2/25 15:48
       * @description 標題
       * @package com.itheima
       */
      @SpringBootApplication
      @EnableDiscoveryClient
      @MapperScan(basePackages = "com.itheima.article.mapper")
      public class ArticleApplication {
          public static void main(String[] args) {
              SpringApplication.run(ArticleApplication.class, args);
          }
      
          @Bean
          public PaginationInterceptor paginationInterceptor() {
              return new PaginationInterceptor();
          }
      }
      
      spring:
        profiles:
          active: dev
      ---
      server:
        port: 9003
      spring:
        application:
          name: leadnews-article
        profiles: dev
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_article?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.article.pojo
      ---
      server:
        port: 9003
      spring:
        application:
          name: leadnews-user
        profiles: pro
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_article?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.article.pojo
      ---
      server:
        port: 9003
      spring:
        application:
          name: leadnews-user
        profiles: test
        datasource:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://192.168.211.136:3306/leadnews_article?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
          username: root
          password: 123456
        cloud:
          nacos:
            server-addr: 192.168.211.136:8848
            discovery:
              server-addr: ${spring.cloud.nacos.server-addr}
      # 設置Mapper接口所對應的XML文件位置,如果你在Mapper接口中有自定義方法,需要進行該配置
      mybatis-plus:
        mapper-locations: classpath*:mapper/*.xml
        # 設置別名包掃描路徑,通過該屬性可以給包中的類注冊別名
        type-aliases-package: com.itheima.article.pojo
      

      (3)代碼生成器生成代碼放到對應位置,copy步驟省略 ,最終效果如下

      1614240113794

      5 實現業務功能

      5.1 實現審核用戶通過和駁回

      5.1.1 需求分析

      通過:

      1614240743081

      點擊通過之后,直接發送請求到后臺 后臺接收到請求之后更新狀態即可,我們可以定義一個controller 和service dao 接收該請求的處理即可。

      請求:/apUserRealname/pass/{id}  PUT
      參數:id 用戶實名認證的記錄的ID
      返回值:Result 返回成功與否即可
      

      駁回:

      1614241131805

      點擊提交之后,直接發送請求 攜帶拒絕的原因信息到后臺 后臺接收到請求之后更新狀態即可。

      我們可以定義一個controller 和service dao 接收該請求的處理即可。

      表結構如下:

      1614258279963

      5.1.2 功能實現

      (1)編寫controller

      1614241490563

      //審核通過
      @PutMapping("/pass/{id}")
      public Result pass(@PathVariable(name="id") Integer id){
          apUserRealnameService.pass(id);
          return Result.ok();
      }
      
      //駁回
      @PutMapping("/reject/{id}")
      public Result reject(@PathVariable(name="id")Integer id,@RequestParam(required = true,name="reason") String reason){
          apUserRealnameService.reject(id,reason);
          return Result.ok();
      }
      

      (2)編寫業務代碼

      實現駁回功能

      業務接口:

      public interface ApUserRealnameService extends IService<ApUserRealname> {
      
          
         
      
          void reject(Integer id, String reason);
      
      }
      

      實現類:

      @Service
      public class ApUserRealnameServiceImpl extends ServiceImpl<ApUserRealnameMapper, ApUserRealname> implements ApUserRealnameService {
      
      
          @Autowired
          private ApUserRealnameMapper apUserRealnameMapper;
        
      
          @Override
          public void reject(Integer id, String reason) {
              ApUserRealname apUserRealname = new ApUserRealname();
              apUserRealname.setId(id);
              apUserRealname.setReason(reason);
              //更新時間
              apUserRealname.setUpdatedTime(LocalDateTime.now());
              //設置狀態為審核失敗
              apUserRealname.setStatus(BusinessConstants.ApUserRealnameConstants.SHENHE_FAILE);
              apUserRealnameMapper.updateById(apUserRealname);
          }
      }
      

      創建常量接口:

      1614244841396

      public interface BusinessConstants {
          //實名認證相關
         public static class ApUserRealnameConstants{
              //創建中
              public static final Integer SHENHE_ING=0;
              //待審核
              public static final Integer SHENHE_WARTING=1;
              //審核失敗
              public static final Integer SHENHE_FAILE=2;
              //審核通過
              public static final Integer SHENHE_SUCESS=9;
          }
      
      }
      

      常量接口 用于 做業務常量 由于有許多的業務,所以在接口中添加靜態內部類進行設置。用來區分不同的業務。

      實現審核通過功能

      業務接口:

      public interface ApUserRealnameService extends IService<ApUserRealname> {
      
          //審核通過
          void pass(Integer id);
      
          //略
          
      
      }
      

      實現類:

      @Autowired
      private ApUserRealnameMapper apUserRealnameMapper;
      
      @Override
      public void pass(Integer id) {
          ApUserRealname entity = new ApUserRealname();
          entity.setId(id);
          //審核通過
          entity.setStatus(BusinessConstants.ApUserRealnameConstants.SHENHE_SUCESS);
          apUserRealnameMapper.updateById(entity);
      
          //todo feign遠程調用 自媒體服務 創建自媒體賬號
      
          //todo feign遠程調用 文章微服務 創建作者賬號
      
      }
      

      1614248534953

      5.2 實現Feign遠程調用

      1614257716124

      相關表如下:

      自媒體表:

      1614258332480

      作者表:

      1614258361359

      5.2.1 實現自媒體遠程調用

      操作步驟如下:

      (1) 添加依賴
      
      (2) 創建feign接口
      
      (3) 實現feign接口(業務實現)
      
      (4) 調用Feign接口實現創建自媒體賬號
      

      (1) 添加依賴

      由于feign 每一個都要用到,以及還需要用到common中的result類,所以在itheima-leadnews-api下添加依賴如下:

      1614257849619

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>itheima-leadnews</artifactId>
              <groupId>com.itheima</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>itheima-leadnews-api</artifactId>
          <packaging>pom</packaging>
          <description>所有feign pojo所在父工程</description>
          <modules>
              <module>itheima-leadnews-admin-api</module>
              <module>itheima-leadnews-user-api</module>
              <module>itheima-leadnews-wemedia-api</module>
              <module>itheima-leadnews-article-api</module>
          </modules>
          <dependencies>
              <dependency>
                  <groupId>com.baomidou</groupId>
                  <artifactId>mybatis-plus-boot-starter</artifactId>
              </dependency>
      
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-openfeign</artifactId>
              </dependency>
      
              <dependency>
                  <groupId>com.itheima</groupId>
                  <artifactId>itheima-leadnews-common</artifactId>
                  <version>1.0-SNAPSHOT</version>
              </dependency>
          </dependencies>
      
      </project>
      

      (2) 創建feign接口(位置如圖)

      1614257954582

      @FeignClient(name="leadnews-wemedia",path = "/wmUser")
      public interface WmUserFeign {
          //創建自媒體賬戶信息
          @PostMapping
          public Result save(@RequestBody WmUser wmUser);
      
          /**
           * 根據apUserId獲取
           * @param apUserId
           * @return
           */
          @GetMapping("/one/{apUserId}")
          public WmUser getByApUserId(@PathVariable(name="apUserId") Integer apUserId);
      }
      

      (3) 實現feign接口(業務實現)在controller中

      1614258007377

      @GetMapping("/one/{apUserId}")
      public WmUser getByApUserId(@PathVariable(name="apUserId") Integer apUserId){
          QueryWrapper<WmUser> queryWrapper = new QueryWrapper<WmUser>();
          queryWrapper.eq("ap_user_id",apUserId);
          WmUser wmUser = wmUserService.getOne(queryWrapper);
          return wmUser;
      }
      

      還有一個接口不需要實現:因為抽象類中早已實現了:

      1614258082737

      (4)調用Feign接口實現創建自媒體賬號

      itheima-leadnews-service-user微服中添加使用到的依賴并Feign開啟接口掃描:

      <dependency>
          <groupId>com.itheima</groupId>
          <artifactId>itheima-leadnews-wemedia-api</artifactId>
          <version>1.0-SNAPSHOT</version>
      </dependency>
      

      XML如下圖:

      1614259084265

      開啟掃描如下圖:*** 號代表占位符,表示任意的包名**

      1614258120346

      通過審核業務實現類中實現遠程調用:

      private static final Logger logger = LoggerFactory.getLogger(ApUserRealnameServiceImpl.class);
      
      @Autowired
      private ApUserRealnameMapper apUserRealnameMapper;
      
      @Autowired
      private WmUserFeign wmUserFeign;
      
      @Autowired
      private ApUserMapper apUserMapper;
      @Override
      public void pass(Integer id) {
          ApUserRealname entity = new ApUserRealname();
          entity.setId(id);
          //審核通過
          entity.setStatus(BusinessConstants.ApUserRealnameConstants.SHENHE_SUCESS);
          apUserRealnameMapper.updateById(entity);
      
          //todo feign遠程調用 自媒體服務 創建自媒體賬號
          ApUserRealname apUserRealname = apUserRealnameMapper.selectById(id);
          if (apUserRealname != null) {
              ApUser apUser = apUserMapper.selectById(apUserRealname.getUserId());
              //判斷是否已經存在
              WmUser wmUser = wmUserFeign.getByApUserId(apUser.getId());
              if (wmUser == null) {
                   wmUser = new WmUser();
                  //copy數據到wmUser中
                  BeanUtils.copyProperties(apUser, wmUser);
                  //設置狀態
                  wmUser.setStatus(BusinessConstants.WmUserConstants.WM_USER_OK);
                  //設置APP用戶的ID
                  wmUser.setApUserId(apUser.getId());
                  //設置創建時間
                  wmUser.setCreatedTime(LocalDateTime.now());
                  Result result = wmUserFeign.save(wmUser);
                  if (result.isSuccess()) {
                      logger.info("自媒體賬號創建成功");
                  }
              }
              //todo feign遠程調用 文章微服務 創建作者賬號
          }
      
      }
      

      在業務接口常量接口中 創建靜態內部常量類:

      public static class WmUserConstants{
             //有效
             public static final Integer WM_USER_OK= 9;
             //凍結
             public static final Integer WM_USER_LOCKED= 0;
             //永久失效
             public static final Integer WM_USER_INVALID= 1;
       }
      

      1614258447396

      5.2.2 實現文章遠程調用

      操作步驟如下:

      (1) 添加依賴
      
      (2) 創建feign接口
      
      (3) 實現feign接口(業務實現)
      
      (4)調用Feign接口實現創建作者賬號
      

      (1) 添加依賴

      忽略,上一個步驟已經做了。就是添加openfeign

      (2) 創建feign接口

      1614260217043

      @FeignClient(name="leadnews-article",path = "/apAuthor")
      public interface ApAuthorFeign {
          //保存作者賬號
          @PostMapping
          public Result save(@RequestBody ApAuthor apAuthor);
      
          /**
           * 根據APP用戶的ID 獲取 作者信息
           * @param apUserId
           * @return
           */
          @GetMapping("/one/{apUserId}")
          public ApAuthor getByApUserId(@PathVariable(name="apUserId")Integer apUserId);
      }
      

      (3) 實現feign接口(業務實現)

      1614260284662

         /**
           * 根據app用戶的ID 獲取作者信息
           * @param apUserId
           * @return
           */
          @GetMapping("/one/{apUserId}")
          public ApAuthor getByApUserId(@PathVariable(name="apUserId")Integer apUserId){
              QueryWrapper<ApAuthor> queryWrapper = new QueryWrapper<ApAuthor>();
              queryWrapper.eq("user_id",apUserId);
              ApAuthor apAuthor = apAuthorService.getOne(queryWrapper);
              return apAuthor;
          }
      

      還有一個保存作者 不需要實現了,因為咱們抽象類中已經完成,你只需要進行聲明即可。

      (4)添加依賴并調用Feign接口實現創建作者賬號

      1614260359900

      <dependency>
          <groupId>com.itheima</groupId>
          <artifactId>itheima-leadnews-wemedia-api</artifactId>
          <version>1.0-SNAPSHOT</version>
      </dependency>
      

      在通過審核的業務代碼的實現類中進行遠程調用:

      private static final Logger logger = LoggerFactory.getLogger(ApUserRealnameServiceImpl.class);
      
      @Autowired
      private ApUserRealnameMapper apUserRealnameMapper;
      
      @Autowired
      private WmUserFeign wmUserFeign;
      
      
      @Autowired
      private ApAuthorFeign apAuthorFeign;
      
      @Autowired
      private ApUserMapper apUserMapper;
      
      @Override
      public void pass(Integer id) {
          ApUserRealname entity = new ApUserRealname();
          entity.setId(id);
          //審核通過
          entity.setStatus(BusinessConstants.ApUserRealnameConstants.SHENHE_SUCESS);
          apUserRealnameMapper.updateById(entity);
      
          //todo feign遠程調用 自媒體服務 創建自媒體賬號
          ApUserRealname apUserRealname = apUserRealnameMapper.selectById(id);
          if (apUserRealname != null) {
              ApUser apUser = apUserMapper.selectById(apUserRealname.getUserId());
              //判斷是否已經存在
              WmUser wmUser = wmUserFeign.getByApUserId(apUser.getId());
              if (wmUser == null) {
                  //copy數據到wmUser中
                  wmUser = new WmUser();
                  BeanUtils.copyProperties(apUser, wmUser);
                  //設置狀態
                  wmUser.setStatus(BusinessConstants.WmUserConstants.WM_USER_OK);
                  //設置APP用戶的ID
                  wmUser.setApUserId(apUser.getId());
                  //設置創建時間
                  wmUser.setCreatedTime(LocalDateTime.now());
                   Result<WmUser> result = wmUserFeign.save(wmUser);
                  if (result.isSuccess()) {
                      logger.info("自媒體賬號創建成功");
                      wmUser = result.getData();
                  }
              }
              //todo feign遠程調用 文章微服務 創建作者賬號
              ApAuthor apAuthor = apAuthorFeign.getByApUserId(apUser.getId());
              if(apAuthor==null){
                  apAuthor = new ApAuthor();
                  //作者名稱就是登錄名
                  apAuthor.setName(apUser.getName());
                  apAuthor.setType(BusinessConstants.ApAuthorConstants.A_MEDIA_USER);
                  apAuthor.setCreatedTime(LocalDateTime.now());
                  apAuthor.setUserId(apUser.getId());
                  apAuthor.setWmUserId(wmUser.getId());
                  apAuthorFeign.save(apAuthor);
              }
          }
      
      }
      

      創建常量類:

      1614260433486

      public static class ApAuthorConstants{
          /**
               * 平臺自媒體人
               */
          public static final Integer A_MEDIA_USER= 2;
          //合作商
          public static final Integer A_MEDIA_SELLER= 1;
          //普通作者
          public static final Integer A_MEDIA_ZERO= 0;
      }
      

      5.2.3 網關對接user微服務

      在admin網關的yml文件中進行配置如下:

      1622776532161

              - id: user
                uri: lb://leadnews-user
                predicates:
                  - Path=/user/**
                filters:
                  - StripPrefix= 1
      

      5.3 測試

      通過網關登錄,登錄之后再進行測試校驗。

      6 feign抽取

      6.1 分析

      我們發現,如果每一個feign都有相關的針對單表的操作,那么每一個都寫一個樣的代碼是不合理的而且是麻煩的,那么我們可以參考抽取controller一樣的方式去抽取feign ,我們不搞那么復雜,因為feign只是接口聲明,

      子類繼承接口即可。

      1616247864736

      如圖,就是 每一個業務接口 繼承 定義了抽取了通用的方法的接口 ,然后每一個業務接口如果是基本的CRUD,都不用進行聲明了。直接調用即可。
      

      6.2 代碼實現抽取

      創建核心feign接口

      1614302046920

      代碼如下:

      package com.itheima.core.feign;
      
      import com.itheima.common.pojo.PageInfo;
      import com.itheima.common.pojo.PageRequestDto;
      import com.itheima.common.pojo.Result;
      import org.springframework.web.bind.annotation.*;
      
      import java.io.Serializable;
      import java.util.List;
      
      /**
       * @author ljh
       * @version 1.0
       * @date 2021/2/26 09:06
       * @description 標題
       * @package com.itheima.core.feign
       */
      public interface CoreFeign<T> {
      
          @DeleteMapping("/{id}")
          public Result deleteById(@PathVariable(name = "id") Serializable id) ;
          /**
           * 添加記錄
           *
           * @param record
           * @return
           */
          @PostMapping
          public Result<T> save(@RequestBody T record) ;
      
          //更新數據
          @PutMapping
          public Result updateByPrimaryKey(@RequestBody T record) ;
      
      
          @GetMapping("/{id}")
          public Result<T> findById(@PathVariable(name = "id") Serializable id) ;
      
          @GetMapping
          public Result<List<T>> findAll() ;
      
      
          /**
           * 通用條件分頁查詢
           *
           * @param pageRequestDto
           * @return
           */
          @PostMapping(value = "/search")
          public Result<PageInfo<T>> findByPage(@RequestBody PageRequestDto<T> pageRequestDto) ;
      
      
      }
      
      

      添加依賴:

      1614302347605

      修改Feign接口:

      1614302396689

      1614302427561

      再測試也是一樣的效果,這樣就不用重復編寫了,

      但是要注意的是:請求路徑不能和父接口(coreFeign)中的一樣。

      7 使用okhttp(可選項)

      ? 在使用默認的feign的時候,feign底層實際上是使用restTemplete 而restTemplate底層又使用到了httpclient,默認使用java自帶的httpUrlConnection。我們是可以使用okhttp ,默認的feign調用httpUrlConnection每次都會創建一個鏈接對象。效率較低。所以使用okhttp來替換,它可以使用連接池。調用效率較高。

      在itheima-leadnews-core-feign微服務中的pom.xml中添加依賴

      <dependency>
          <groupId>io.github.openfeign</groupId>
          <artifactId>feign-okhttp</artifactId>
      </dependency>
      

      1616247691225

      在需要用到feign的微服務中配置如下即可

      feign:
        client:
          config:
            default: # default指定的是所有的 被調用方  都設置為該配置超時時間,可以設置為某一個微服務對應的服務名
              connectTimeout: 5000 # 鏈接超時時間
              readTimeout: 5000 # 讀取的超時時間
        okhttp:
          enabled: true
        httpclient:
          enabled: false
      

      8 網關整合knife4j

      每次我們測試都需要通過POSTMAN 結合網關來測試,這樣麻煩,我們可以集成到knife4j上去進行測試。如下:

      (1)創建三個類在網關中

      1622007474256

      從此處copy

      1622007530472

      (2)admin微服務中創建配置類:如果有則不用創建了。

      package com.itheima.admin.config;
      
      import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.Import;
      import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
      import springfox.documentation.builders.ApiInfoBuilder;
      import springfox.documentation.builders.PathSelectors;
      import springfox.documentation.builders.RequestHandlerSelectors;
      import springfox.documentation.service.ApiInfo;
      import springfox.documentation.service.Contact;
      import springfox.documentation.spi.DocumentationType;
      import springfox.documentation.spring.web.plugins.Docket;
      import springfox.documentation.swagger2.annotations.EnableSwagger2;
      
      import java.util.HashSet;
      
      @Configuration
      @EnableSwagger2//啟用swagger
      @EnableKnife4j//啟用Knife4j
      @Import(BeanValidatorPluginsConfiguration.class)
      public class SwaggerConfiguration {
      
         /*@Bean
         public Docket buildDocket() {
            HashSet<String> strings = new HashSet<>();
            strings.add("application/json");
      
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(buildApiInfo())
                    //設置返回值數據類型為json
                    .produces(strings)//設置響應的結果的數據類型 變成JSON
                    .select()
                    // 要掃描的API(Controller)基礎包
                    .apis(RequestHandlerSelectors.basePackage("com.itheima.admin.controller"))
                    //針對那些路徑生成API文檔 /**
                    .paths(PathSelectors.any())
                    .build();
         }
      
         private ApiInfo buildApiInfo() {
            Contact contact = new Contact("黑馬程序員","","");
            return new ApiInfoBuilder()
                    .title("黑馬頭條-平臺管理API文檔")
                    .description("平臺管理服務api")
                    .contact(contact)
                    .version("1.0.0").build();
         }*/
         @Bean
         public Docket buildDocket() {
            HashSet<String> strings = new HashSet<>();
            strings.add("application/json");
            Docket docket=new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(buildApiInfo())
                    //設置返回數據類型
                    .produces(strings)
                    //分組名稱
                    //.groupName("1.0")
                    .select()
                    //這里指定Controller掃描包路徑
                    .apis(RequestHandlerSelectors.basePackage("com.itheima.admin.controller"))
                    //**
                    .paths(PathSelectors.any())
                    .build();
            return docket;
         }
         private ApiInfo buildApiInfo() {
            Contact contact = new Contact("黑馬程序員","","");
            return new ApiInfoBuilder()
                    .title("黑馬頭條-平臺管理API文檔")
                    .description("平臺管理服務api")
                    .contact(contact)
                    .version("1.0.0").build();
         }
      }
      

      (3)過濾器中添加如下代碼

      1622007637109

      (4)啟動網關 和微服務測試:通過網關地址進行訪問

      1622007663814

      登錄:

      1622007722836

      根據登錄之后獲取到的token 在全局參數中添加之后,就可以直接測試了:

      1622007790772

      測試訪問:

      1622007857581

      posted on 2022-04-25 00:43  ofanimon  閱讀(188)  評論(0)    收藏  舉報
      // 側邊欄目錄 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css
      主站蜘蛛池模板: 无码人妻一区二区三区av| a级国产乱理伦片在线观看al| 在线日韩一区二区| 亚洲精品在线二区三区| 久久精品av国产一区二区| 国产精品日日摸夜夜添夜夜添无码| 老司机午夜免费精品视频| 欧美大肥婆大肥bbbbb| 亚洲精品一区二区三天美| 怡春院久久国语视频免费| 亚洲欧美偷国产日韩| 国产精品自拍视频我看看| 给我免费观看片在线| 亚洲成人av在线综合| 午夜好爽好舒服免费视频| 成人3D动漫一区二区三区| 日本边添边摸边做边爱的网站| 成熟女人特级毛片www免费| 黑森林福利视频导航 | 平昌县| 久久自己只精产国品| 国内精品一区二区不卡| 40岁成熟女人牲交片20分钟| 亚洲天天堂天堂激情性色| 亚洲日本欧洲二区精品| 中文字幕人妻无码一区二区三区| 亚洲人成亚洲人成在线观看| 五月开心六月丁香综合色啪| 国产亚洲精品久久久久久大师| 精品九九人人做人人爱| 亚洲精品尤物av在线网站| 国内精品久久人妻无码网站| 午夜成人性爽爽免费视频| 无码人妻一区二区三区线| 99精品久久精品| 久爱www人成免费网站| 亚洲の无码国产の无码步美| 欧美成人性色一区欧美成人性色区 | 三级国产在线观看| 无码视频伊人| 一区二区三区精品偷拍|