文章目录
一、Nginx鉴权 1. 依赖模块 2. Nginx配置 3. Rest接口
二、Nginx限流
一、Nginx鉴权
1. 依赖模块
依赖模块 http_auth_request_module 验证是否安装
nginx -V 2 >&1 | grep -- 'http_auth_request_module'
2. Nginx配置
server
{
listen 80 ;
location = /checkToken {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "" ;
proxy_set_header via $request_uri ;
proxy_pass $auth_request_url ;
}
location = /auth401 {
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate" ;
if ( $arg_via = "001" ) {
return 401 "{\" msg\" :\" 登录凭证为空\" ,\" opCode\" :\" 001\" ,\" operateSuccess\" :false}" ;
}
if ( $arg_via = "002" ) {
return 401 "{\" msg\" :\" 登录凭证失效\" ,\" opCode\" :\" 002\" ,\" operateSuccess\" :false}" ;
}
if ( $arg_via = "003" ) {
return 401 "{\" msg\" :\" 账户无权限\" ,\" opCode\" :\" 003\" ,\" operateSuccess\" :false}" ;
}
}
location /test/api/ {
set $auth_request_url "http://127.0.0.1:8080/test/api/token/check?token=$arg_token " ;
auth_request /checkToken;
auth_request_set $auth_via $upstream_http_via ;
error_page 401 = /auth401?via= $auth_via ;
proxy_pass http://127.0.0.1:8080/test/api/;
}
}
3. Rest接口
验证的Redis账户权限内容 TokenRest.java
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Set;
@RestController
@RequestMapping( "/api/token" )
public class TokenRest {
@Resource
private RedisTemplate redisTemplate;
@GetMapping( value= "check" )
public void checkRest( HttpServletRequest request, HttpServletResponse response) {
response.setStatus( 401 ) ;
try {
String url = request.getHeader( "via" ) ;
if ( StringUtils.isNotEmpty( url) && url.contains( "?" )) {
url = url.substring( 0 , url.indexOf( "?" )) ;
}
// 白名单跳过验证
String flag = ( String) redisTemplate.opsForHash( ) .get( "whiteCache" , url) ;
if ( StringUtils.isNotEmpty( flag)) {
response.setStatus( 200 ) ;
return ;
}
// 从Head或url中获取token
String token = request.getParameter( "token" ) ;
if ( StringUtils.isEmpty( token) || "null" .equals( token)) {
token = request.getHeader( "Authorization" ) ;
if ( token!= null && token.startsWith( "Bearer " )) {
token = token.substring( 7 ) ;
}
}
if ( StringUtils.isEmpty( token) || "null" .equals( token)) {
response.setHeader( "via" , "001" ) ;
return ;
}
// 从Redis中获取账户信息
String accountId = ( String) redisTemplate.opsForValue( ) .get( token) ;
if ( accountId == null) {
response.setHeader( "via" , "002" ) ;
return ;
}
Map< String, String> info = ( Map< String, String> ) redisTemplate.opsForValue( ) .get( accountId) ;
if ( info == null) {
response.setHeader( "via" , "003" ) ;
return ;
}
String[ ] roleIds = info.get( "roles" ) .split( "," ) ;
for ( String roleId : roleIds) {
Set< String> securityUrls = ( Set< String> ) redisTemplate.opsForHash( ) .get( "funcCache" ,roleId) ;
if ( securityUrls.contains( url)) {
flag = "1" ;
break ;
}
}
if ( "1" .equals( flag)) {
response.setStatus( 200 ) ;
} else {
response.setHeader( "via" , "003" ) ;
}
} catch ( Exception e) {
System.err.println( e.getMessage( )) ;
}
}
}
二、Nginx限流
1. 简介
Nginx限流是一种用于保护系统资源、防止恶意攻击和控制流量的技术。 控制速率:使用 ngx_http_limit_req_module
模块,可以限制每个IP地址单位时间内的请求数。 控制连接数:使用 ngx_http_limit_conn_module
模块,可以限制每个IP地址同时保持的连接数。
2. 控制速率
http
{
limit_req_zone $binary_remote_addr zone = limit_req:10m rate = 2r/s;
}
项 说明 binary_remote_addr 表示通过客户端IP来限制 zone 共享内存区存储访问信息 limit_req:10m 名字为limit_req的内存区域,存储16万IP地址 rate=2r/s 表示每秒最多处理2个请求
server
{
location = /test.htm {
limit_req zone = limit_req burst = 10 nodelay;
alias C:/nginx/html/test.htm;
}
}
项 说明 burst=10 突发请求不超过10个 nodelay 不延迟处理超过限制的请求
2. 控制连接数
http
{
limit_conn_zone $binary_remote_addr zone = limit_conn:10m;
}
项 说明 binary_remote_addr 表示通过客户端IP来限制 zone 共享内存区存储访问信息 limit_conn:10m 名字为limit_conn的内存区域,存储16万IP地址
server
{
location = /test.htm {
limit_conn limit_conn 2 ;
alias C:/nginx/html/test.htm;
}
}
项 说明 limit_conn 2 同一个IP地址只允许保持2个连接