1. 你要有一台服务器并安装openresty
这里以centos7为例子
# add the yum repo:
wget https://openresty.org/package/centos/openresty.repo
sudo mv openresty.repo /etc/yum.repos.d/openresty.repo
# update the yum index:
sudo yum check-update
sudo yum install -y openresty
2. 安装jwt插件
https://github.com/cdbattags/lua-resty-jwt
下载后将”lib/resty”目录内的文件放到”openresty”默认的目录中“lualib/resty”
3. 配置openresty规则
server {
listen 443 ssl;
#server_name weauth.example.com;
resolver 8.8.8.8; # 调用企业微信接口需要设置 DNS
#ssl_certificate /usr/local/openresty/cert/weauth.example.com.crt;
#ssl_certificate_key /usr/local/openresty/cert/weauth.example.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2;
#ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
lua_ssl_verify_depth 2;
lua_ssl_trusted_certificate /etc/pki/tls/certs/ca-bundle.crt;
set $jwt_secret "your-own-jwt-secret";
location / {
#access_by_lua_file /usr/local/openresty/nginx/lua/guard.lua;
access_by_lua '
local jwt = require "resty.jwt"
local validators = require "resty.jwt-validators"
local jwt_token = ngx.var.arg_jwt
local auth_header = ngx.var.http_Authorization
local _token
if auth_header then
_,_,_token = string.find(auth_header, "Bearer%s+(.+)")
end
if jwt_token then
ngx.header['Set-Cookie'] = "jwt=" .. jwt_token
else
jwt_token = ngx.var.cookie_jwt or _token
end
local claim_spec = {
exp = validators.is_not_expired() --// To check expiry
}
local jwt_obj = jwt:verify(ngx.var.jwt_secret, jwt_token)
if not jwt_obj["verified"] then
--local site = ngx.var.scheme .. "://" .. ngx.var.http_host;
--local args = ngx.req.get_uri_args();
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header["Content-Type"] = "application/json"
--ngx.header["Content-Type"] = "text/html"
ngx.say("{\"msg\":" ,"\"",jwt_obj.reason,"\"","}");
ngx.exit(ngx.HTTP_OK)
-- or you can redirect to your website to get a new jwt token
-- -- then redirect back
--return
-- else
-- ngx.redirect("https://test.com")
end
';
proxy_pass http://httpbin.org/;
proxy_set_header X-Scheme $scheme;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:$server_port;
}
location = /verify { #验证
# default_type text/plain;
access_by_lua_block {
local cjson = require "cjson"
local jwt = require "resty.jwt"
local jwt_token = ngx.var.arg_jwt
local jwt_obj = jwt:verify(ngx.var.jwt_secret,jwt_token)
if not jwt_obj["verified"] then
ngx.status = ngx.HTTP_UNAUTHORIZED
--ngx.header["Content-Type"] = "text/html"
ngx.header["Content-Type"] = "application/json"
ngx.say("{\"msg\":" ,"\"",jwt_obj.reason,"\"","}");
ngx.exit(ngx.HTTP_OK)
else
ngx.header["Content-Type"] = "application/json"
ngx.say(cjson.encode(jwt_obj))
end
}
}
location = /sign { #生成
default_type text/plain;
content_by_lua '
local cjson = require "cjson"
local jwt = require "resty.jwt"
local jwt_token = jwt:sign(
ngx.var.jwt_secret,
{
header={typ="JWT", alg="HS256"},
payload={foo="bar",
iss="yd", --签发人
iat=ngx.time(), --签发时间
nbf=ngx.time()+30, --生效时间
exp=ngx.time()+3600 --过期时间
}
}
)
ngx.say(jwt_token)
';
}
}
4. 使用方式
1. 根据需求调整“sign”配置,获取“token“
curl -s https://xxxx.xx/sign
2. 将获取到的”token”添加到请求地址
curl 'https://xxxx.xx/get?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpc3MiOiJ5ZCIsImlhdCI6MTcwODY4Mzk2MCwibmJmIjoxNzA4NjgzOTkwLCJleHAiOjE3MDg2ODc1NjB9.un7HYSTX7eYpY5puop8-Q_aU69KzSMcdp_Q25xlMivg'
curl 'https://xxxx.xx/anything/1get?1=a&2=s' -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpc3MiOiJ5ZCIsImlhdCI6MTcwODY4Mzk2MCwibmJmIjoxNzA4NjgzOTkwLCJleHAiOjE3MDg2ODc1NjB9.un7HYSTX7eYpY5puop8-Q_aU69KzSMcdp_Q25xlMivg'
3. 验证”token”
curl -s https://xxxx.xx/verify?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJpc3MiOiJ5ZCIsImlhdCI6MTcwODY4Mzk2MCwibmJmIjoxNzA4NjgzOTkwLCJleHAiOjE3MDg2ODc1NjB9.un7HYSTX7eYpY5puop8-Q_aU69KzSMcdp_Q25xlMivg