nginx+openResty
Posted qq_40707462
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx+openResty相关的知识,希望对你有一定的参考价值。
一、nginx
1、好处
1、处理响应请求很快
2、高并发连接。理论上,Nginx 支持的并发连接上限取决于你的内存,10 万远未封顶。
3、低的内存消耗。10000 个非活跃的 HTTP Keep-Alive 连接在 Nginx 中仅消耗 2.5MB 的内存
4、具有很高的可靠性:
5、高扩展性。各模块耦合度极低。这种设计造就了 Nginx 庞大的第三方模块。
6、热部署。master 管理进程与 worker 工作进程的分离设计,可以在 7 × 24 小时不间断服务的前提下,升级 Nginx 的可执行文件。也可以在不停止服务的情况下修改配置文件,更换日志文件等功能。
2、安装
3、配置
nginx.conf
是主配置文件
worker_process # 表示工作进程的数量,一般设置为cpu的核数
worker_connections # 表示每个工作进程的最大连接数
server # 块定义了虚拟主机
listen # 监听端口
server_name # 监听域名
location # 是用来为匹配的 URI 进行配置,URI 即语法中的“/uri/”
location / # 匹配任何查询,因为所有请求都以 / 开头
root # 指定对应uri的资源查找路径,这里html为相对路径,完整路径为
# /opt/nginx-1.7.7/html/
index # 指定首页index文件的名称,可以配置多个,以空格分开。如有多
# 个,按配置顺序查找。
示例
从配置可以看出,Nginx 监听了 80 端口、域名为 localhost、根路径为 html 文件夹(如果安装路径为 /opt/nginx-1.7.7
,所以完整根路径为 /opt/nginx-1.7.7/html
)、默认 index 文件为 index.html
,index.htm
服务器错误重定向到 50x.html
页面。
可以看到 /opt/nginx-1.7.7/html/
有以下文件:
ubuntu:/opt/nginx-1.7.7/html$ ls
50x.html index.html
这也是上面在浏览器中输入 http://localhost,能够显示欢迎页面的原因。实际上访问的是 /opt/nginx-1.7.7/html/index.html 文件。
4、location匹配
模式 | 含义 |
---|---|
location = /uri = | 表示精确匹配,只有完全匹配上才能生效 |
location ^~ /uri ^~ | 开头对URL路径进行前缀匹配,并且在正则之前。 |
location ~ pattern | 开头表示区分大小写的正则匹配 |
location ~* pattern | 开头表示不区分大小写的正则匹配 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 |
location / | 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default |
5、反向代理
反向代理
反向代理服务器,对于客户端而言它就像是原始服务器,客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样
- 反向代理还可以为后端的多台服务器提供负载均衡,或为后端较慢的服务器提供缓冲服务。
- 反向代理还可以启用高级 URL 策略和管理技术,从而使处于不同 web 服务器系统的 web 页面同时存在于同一个 URL 空间下。
二、openResty+jwt
1、安装
添加仓库
# add the yum repo:
wget https://openresty.org/package/centos/openresty.repo
sudo mv openresty.repo /etc/yum.repos.d/
# update the yum index:
sudo yum check-update
安装
# 安装 OpenResty
$ sudo yum install -y openresty
# 安装命令行工具 resty
$ sudo yum install -y openresty-resty
# 安装命令行工具 opm
$ sudo yum install -y openresty-opm
列出所有 openresty 仓库里头的软件包:
sudo yum --disablerepo="*" --enablerepo="openresty" list available
路径,系统默认安装在 /usr/local/openresty
[wjy@localhost ~]$ whereis openresty
openresty: /usr/bin/openresty /usr/local/openresty
[wjy@localhost ~]$ cd /usr/local/openresty
[wjy@localhost openresty]$ ls
bin luajit nginx pcre resty.index zlib
COPYRIGHT lualib openssl111 pod site
[wjy@localhost openresty]$ cd bin
[wjy@localhost bin]$ ./openresty -v
nginx version: openresty/1.21.4.1
在profile中添加到path
(记得切换root,不然保存会报错profile" E212: 无法打开并写入文件
,这样的话保存时用 w ! sudo tee %
)
vim /etc/profile
PATH=/usr/local/openresty/nginx/sbin:$PATH
export PATH
重新加载环境
source /etc/profile
2、测试
在 /usr/local/openresty/nginx/conf
里,修改nginx.conf
,在合适的位置
修改完conf要重新启动一下nginx -s reload
worker_processes 1;
error_log logs/error.log;
events
worker_connections 1024;
http
server
listen 8081;
location /
default_type text/html;
content_by_lua_block
ngx.say("<p>hello, world</p>")
未避免权限问题,尽量su root
,或者在nginx.conf加入:
启动nginx
nginx -t
nginx -c conf/nginx.conf
查看是否启动
[root@localhost nginx]# ps aux|grep nginx
root 5731 0.0 0.0 27580 1576 ? Ss 10:40 0:00 nginx: master process nginx
nobody 5732 0.0 0.1 30112 2388 ? S 10:40 0:00 nginx: worker process
root 6046 0.0 0.0 27580 1588 ? Ss 10:50 0:00 nginx: master process nginx
nobody 6047 0.0 0.1 30112 2876 ? S 10:50 0:00 nginx: worker process
root 6095 0.0 0.0 112664 956 pts/0 S+ 10:54 0:00 grep --color=auto nginx
测试:curl http://localhost:8081/
<p>hello, world</p>
错误消息会发送到当前工作目录的 stderr 设备或默认错误日志文件 log/Error.log
3、安装 jwt 插件
sudo opm get SkyLothar/lua-resty-jwt
默认安装在/usr/local/openresty/site
4、测试 jwt
修改 nginx.conf
里面"lua-resty-jwt"
算是一个密钥,可以自己设置,保证verify
和sign
的一样就行
kid是jwt header中的一个可选参数,全称是key ID,它用于指定加密算法的密钥
"alg" : "HS256",
"typ" : "jwt",
"kid" : "/home/jwt/.ssh/pem"
# nginx.conf
lua_package_path "/usr/local/openresty/lualib/mylua/?.lua;;";
server
default_type text/plain;
location = /verify
content_by_lua_block
local cjson = require("cjson")
local jwt = require("resty.jwt")
local jwt_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" ..
".eyJmb28iOiJiYXIifQ" ..
".VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY"
local jwt_obj = jwt:verify("lua-resty-jwt", jwt_token)
ngx.say(cjson.encode(jwt_obj))
location = /sign
content_by_lua_block
local cjson = require("cjson")
local jwt = require("resty.jwt")
local jwt_token = jwt:sign(
"lua-resty-jwt",
header=typ="JWT", alg="HS256",
payload=foo="bar"
)
ngx.say(jwt_token)
lua_package_path
:指定 Lua 脚本位置。搜寻规则
首先会在/usr/local/openresty/site/lualib
中搜寻
例如:lua_package_path "/foo/bar/?.lua;/blah/?.lua;;";
最后出现了 ;; 两个半角分号,代表的是 LuaJIT 安装时的原始搜索路径,如果在前面的搜索路径里面无法搜索到需要的模块,就会依次搜索后面的路径。
default_type
:指定输出为纯文本,无实际作用,只是为了在浏览器中方便查看换行等符号。
测试:
curl http://localhost:8081/verify
"signature": "VAoRL1IU0nOguxURF2ZcKR0SGKE1gCbqwyh8u2MLAyY",
"reason": "everything is awesome~ :p",
"valid": true,
"raw_header": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
"payload":
"foo": "bar"
,
"header":
"alg": "HS256",
"typ": "JWT"
,
"verified": true,
"raw_payload": "eyJmb28iOiJiYXIifQ"
curl http://localhost:8081/sign
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.VxhQcGihWyHuJeHhpUiq2FU7aW2s_3ZJlY6h1kdlmJY
5、例子
在对应位置mylua里写对应的脚本
lua_package_path "/usr/local/openresty/lualib/mylua/?.lua;;";
jwttest.lua
local cjson = require "cjson"
local jwt = require "resty.jwt"
--your secret
local secret = "secretkey"
local M =
function M.auth()
-- require Authorization request header
local auth_header = ngx.var.http_Authorization
if auth_header == nil then
ngx.log(ngx.WARN, "No Authorization header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
ngx.log(ngx.INFO, "Authorization: " .. auth_header)
-- require Bearer token
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
if token == nil then
ngx.log(ngx.WARN, "Missing token")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
ngx.log(ngx.INFO, "Token: " .. token)
local jwt_obj = jwt:verify(secret, token)
if jwt_obj.verified == false then
ngx.log(ngx.WARN, "Invalid token: ".. jwt_obj.reason)
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header.content_type = "application/json; charset=utf-8"
ngx.say(cjson.encode(jwt_obj))
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
ngx.log(ngx.INFO, "JWT: " .. cjson.encode(jwt_obj))
end
return M
nginx.conf
location /checkjwt
access_by_lua_block
local obj = require('jwttest')
obj.auth()
ngx.say("aaaaa")
不带token,401
curl http://localhost:8081/checkjwt
HTTP/1.1 401 Unauthorized
Server: openresty/1.21.4.1
Date: Fri, 19 Aug 2022 02:22:53 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>openresty/1.21.4.1</center>
</body>
</html>
指定token请求(token是事先自己sign的)
curl -i http://localhost:8081/checkjwt -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.VlM9f1OK5gpYtEtOdnuIqxATcnP7ulALjGqsKhjk58Y'
[root@localhost openresty]# curl -i http://localhost:8081/checkjwt -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.VlM9f1OK5gpYtEtOdnuIqxATcnP7ulALjGqsKhjk58Y'
HTTP/1.1 200 OK
Server: openresty/1.21.4.1
Date: Fri, 19 Aug 2022 02:19:34 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: keep-alive
Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.VlM9f1OK5gpYtEtOdnuIqxATcnP7ulALjGqsKhjk58Y
aaaaa
三、
每次登录,客户端向后端发送请求,后端返回一个有过期时间的token给客户端,后端把这个token保存在redis里,之后每次客户端发送请求的时候都带上这个token(放在header里或者cookie里),后端校验
载荷(payload)
该部分一般存放一些有效的信息。jwt的标准定义包含五个字段:
iss:该JWT的签发者
sub: 该JWT所面向的用户
aud: 接收该JWT的一方
exp(expires): 什么时候过期,这里是一个Unix时间戳
iat(issued at): 在什么时候签发的
这个只是JWT的定义标准,不强制使用。另外自己也可以添加一些公开的不涉及安全的方面的信息。
以上是关于nginx+openResty的主要内容,如果未能解决你的问题,请参考以下文章