互联网API开放平台安全设计(五)---APIGateway网关

什么是网关

随着互联网的快速发展,当前以步入移动互联、物联网时代。用户访问系统入口也变得多种方式,由原来单一的PC客户端,变化到PC客户端、各种浏览器、手机移动端及智能终端等。同时系统之间大部分都不是单独运行,经常会涉及与其他系统对接、共享数据的需求。所以系统需要升级框架满足日新月异需求变化,支持业务发展,并将框架升级为微服务架构。“API网关”核心组件是架构用于满足此些需求。

很多互联网平台已基于网关的设计思路,构建自身平台的API网关,国内主要有京东、携程、唯品会等,国外主要有Netflix、Amazon等。

网关框架框架

业界为了满足这些需求,已有相关的网关框架。

1、基于nginx平台实现的网关有:KONG、API Umbrella

2、自研发的网关有:apigee、Zuul

API网关设计

API网关是微服务架构(Microservices Architecture)标准化服务的模式。API网关定位为应用系统服务接口的网关,区别于网络技术的网关,但是原理则是一样。API网关统一服务入口,可方便实现对平台众多服务接口进行管控,对访问服务的身份认证、防报文重放与防数据篡改、功能调用的业务鉴权、响应数据的脱敏、流量与并发控制,甚至基于API调用的计量或者计费等等。组件设计如下:

网关的应用场景

  1. 黑白名单:实现通过IP地址控制禁止访问网关功能,此功能是应用层面控制实现,再往前也可以通过网络传输方面进行控制访问。
  2. 日志:实现访问日志的记录,可用于分析访问、处理性能指标,同时将分析结果支持其他模块功能应用。
  3. 协议适配:实现通信协议校验、适配转换的功能。
  4.  身份认证:负责网关访问身份认证验证,此模块与“访问认证中心”通信,实际认证业务逻辑交移“访问认证中心”处理。
  5. 计流限流:实现微服务访问流量计算,基于流量计算分析进行限流,可以定义多种限流规则。
  6. 路由:路由是API网关很核心的模块功能,此模块实现根据请求,锁定目标微服务并将请求进行转发。此模块需要与“服务发布管理中心”通信。“服务发布管理中心”实现微服务发布注册管理功能,与其通信获得目标微服务信息。

API网关部署

API网关是一个公共基础组件,无状态,可支持多套分布式部署。如下图所示:

基于Nginx实现API网关

Nginx配置

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {

        listen       80;

        server_name  localhost;

        location /api-a {

            proxy_pass   http://127.0.0.1:8000/;

            index  index.html index.htm;

        }

                   location /api-b {

            proxy_pass   http://127.0.0.1:8001/;

            index  index.html index.htm;

        }

    }

}

 

基于Zuul实现API网关

搭建注册中心

创建项目eureka_server

eureka_server pom依赖信息

<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">

      <modelVersion>4.0.0</modelVersion>

      <groupId>com.itmayiedu</groupId>

      <artifactId>eureka_server</artifactId>

      <version>0.0.1-SNAPSHOT</version>

      <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>2.0.1.RELEASE</version>

      </parent>

 

      <!-- 管理依赖 -->

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Finchley.M7</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

      <dependencies>

 

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>

           </dependency>

 

 

      </dependencies>

 

      <!-- 注意: 这里必须要添加, 否者各种依赖有问题 -->

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/libs-milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

</project>

 application.yml  配置信息

server:

  port: 8100

eureka:

  instance:

    hostname: server1

  client:

    serviceUrl:

          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    register-with-eureka: false

    fetch-registry: false

server:

  port: 8100

eureka:

  instance:

    hostname: server1

  client:

    serviceUrl:

          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

    register-with-eureka: false

    fetch-registry: false

 启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
	public static void main(final String[] args) {
		SpringApplication.run(EurekaApplication.class, args);
	}
}

 创建A服务项目

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class AIndexController {
	@RequestMapping("/")
	public String index() {
		return "我是A项目....";
	}

	public static void main(String[] args) {
		SpringApplication.run(AIndexController.class, args);
	}
}

 

server:

  port: 8000

spring:

    application:

        name: itmayiedu_a

eureka:

  client:

    service-url:

           defaultZone: http://localhost:8100/eureka

创建B服务项目

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class AIndexController {
	@RequestMapping("/")
	public String index() {
		return "我是B项目....";
	}

	public static void main(String[] args) {
		SpringApplication.run(AIndexController.class, args);
	}
}

 

server:

  port: 8000

spring:

    application:

        name: itmayiedu_a

eureka:

  client:

    service-url:

           defaultZone: http://localhost:8100/eureka

创建 zuul-gateway 项目

创建 zuul-gateway Pom依赖

 

      <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>2.0.1.RELEASE</version>

           <relativePath /> <!-- lookup parent from repository -->

      </parent>

 

      <properties>

           <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

           <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

           <java.version>1.8</java.version>

           <spring-cloud.version>Finchley.RC1</spring-cloud.version>

      </properties>

      <dependencies>

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-netflix-zuul</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.projectlombok</groupId>

                 <artifactId>lombok</artifactId>

                 <optional>true</optional>

           </dependency>

           <dependency>

                 <groupId>com.alibaba</groupId>

                 <artifactId>fastjson</artifactId>

                 <version>1.2.3</version>

           </dependency>

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>${spring-cloud.version}</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

                 <plugin>

                      <groupId>org.apache.maven.plugins</groupId>

                      <artifactId>maven-compiler-plugin</artifactId>

                      <configuration>

                            <source>1.8</source>

                            <target>1.8</target>

                      </configuration>

                 </plugin>

                 <plugin>

                      <groupId>org.apache.maven.plugins</groupId>

                      <artifactId>maven-resources-plugin</artifactId>

                      <version>3.0.1</version>

                      <executions>

                            <execution>

                                  <id>copy-conf</id>

                                  <phase>package</phase>

                                  <goals>

                                       <goal>copy-resources</goal>

                                  </goals>

                                  <configuration>

                                       <encoding>UTF-8</encoding>

                                        <outputDirectory>${project.build.directory}/ext/conf</outputDirectory>

                                       <resources>

                                             <resource>

                                                  <directory>ext/conf</directory>

                                                  <includes>

                                                        <include>logback.xml</include>

                                                  </includes>

                                                  <filtering>true</filtering>

                                             </resource>

                                       </resources>

                                  </configuration>

                            </execution>

                      </executions>

                 </plugin>

                 <plugin>

                      <groupId>org.jacoco</groupId>

                      <artifactId>jacoco-maven-plugin</artifactId>

                      <version>0.7.5.201505241946</version>

                      <executions>

                            <execution>

                                  <id>default-prepare-agent</id>

                                  <goals>

                                       <goal>prepare-agent</goal>

                                  </goals>

                            </execution>

                            <execution>

                                  <id>default-prepare-agent-integration</id>

                                  <goals>

                                       <goal>prepare-agent-integration</goal>

                                  </goals>

                            </execution>

                      </executions>

                 </plugin>

                 <plugin>

                      <groupId>com.spotify</groupId>

                      <artifactId>docker-maven-plugin</artifactId>

                      <version>0.4.3</version>

                      <configuration>

                            <imageName>hy_uav_gateway</imageName>

                            <dockerDirectory>src/main/docker</dockerDirectory>

                            <resources>

                                  <resource>

                                       <targetPath>/</targetPath>

                                       <directory>${project.build.directory}</directory>

                                       <include>${project.build.finalName}.jar</include>

                                       <include>ext/conf/logback.xml</include>

                                  </resource>

                            </resources>

                      </configuration>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

 配置application 依赖信息

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8100/eureka/

server:

  port: 8769

spring:

  application:

    name: service-zuul

zuul:

  routes:

    api-a:

      path: /api-a/**

      serviceId: itmayiedu_a

    api-b:

      path: /api-b/**

      serviceId: itmayiedu_b

ZuulApplication启动运行

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class ZuulApplication {

	public static void main(String[] args) {
		SpringApplication.run(ZuulApplication.class, args);
	}

	@Bean
	public TokenFilter accessFilter() {
		return new TokenFilter();
	}
}

过滤器拦截参数

// 使用网关拦截Token参数
public class TokenFilter extends ZuulFilter {

	public Object run() throws ZuulException {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		Object accessToken = request.getParameter("accessToken");
		if (accessToken == null) {
			// 返回错误信息
			ctx.setSendZuulResponse(false);
			ctx.setResponseStatusCode(401);
			ctx.setResponseBody("accessToken is null");
			return null;
		}
		return null;
	}

	public boolean shouldFilter() {
		return true;// 是否执行该过滤器,此处为true,说明需要过滤
	}

	@Override
	public int filterOrder() {
		return 0;// 优先级为0,数字越大,优先级越低
	}

	@Override
	public String filterType() {
		return "pre"; // 前置过滤器
	}

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值