一、Nginx鉴权
1. 依赖模块 依赖模块
- 依赖模块
1 | http_auth_request_module |
- 验证是否安装
1 | nginx -V 2>&1 | grep -- 'http_auth_request_module' |
2. Nginx配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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/ { 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 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 info = (Map) redisTemplate.opsForValue().get(accountId); if (info == null ) { response.setHeader( "via" , "003" ); return ; } String[] roleIds = info.get( "roles" ).split( "," ); for (String roleId : roleIds) { Set securityUrls = (Set) 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()); } } } |
- 验证的Redis账户权限内容
二、Nginx限流
1. 简介
Nginx限流是一种用于保护系统资源、防止恶意攻击和控制流量的技术。
- 控制速率:使用
ngx_http_limit_req_module
模块,可以限制每个IP地址单位时间内的请求数。 - 控制连接数:使用
ngx_http_limit_conn_module
模块,可以限制每个IP地址同时保持的连接数。
2. 控制速率
- nginx.conf
1 2 3 4 | 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个请求 |
1 2 3 4 5 6 7 | server { location = /test .htm { limit_req zone=limit_req burst=10 nodelay; alias C: /nginx/html/test .htm; } } |
项 | 说明 |
---|---|
burst=10 | 突发请求不超过10个 |
nodelay | 不延迟处理超过限制的请求 |
3. 控制连接数
- nginx.conf
1 2 3 4 | http { limit_conn_zone $binary_remote_addr zone=limit_conn:10m; } |
项 | 说明 |
---|---|
binary_remote_addr | 表示通过客户端IP来限制 |
zone | 共享内存区存储访问信息 |
limit_conn:10m | 名字为limit_conn的内存区域,存储16万IP地址 |
1 2 3 4 5 6 7 | server { location = /test .htm { limit_conn limit_conn 2; alias C: /nginx/html/test .htm; } } |
项 | 说明 |
---|---|
limit_conn 2 | 同一个IP地址只允许保持2个连接 |
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持IT俱乐部。