Nginx使用OpenResty+Lua+Redis进行token鉴权

背景介绍

公司有很多项目通过sphinx生成了Html文档,通过nginx转发,前进前端界面展示,方便员工查阅和使用。出于安全考虑,现需要添加一个登陆界面,接入公司的统一认证系统,进行账号校验

制定方案通过Oauth2连接公司统一认证系统(spring Oauth2)前端调用Oauth2获取TokenNginx通过token校验实现鉴权功能

此处主要讲Nginx使用Lua脚本连接Redis校验Token是否存在。

使用OpenResty

Nginx 官方是没有 Lua 模块的,所以手动引入 OpenResty 开发的 ngx_http_lua_module不如直接使用 openresty。openresty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

Lua语言

Lua 是一种轻量小巧的脚本语言,用标准 C 语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。基础语法可以参考:https://www.runoob.com/lua/lua-tutorial.html

代码逻辑处理获取Token

开始代码编写,第一步是从请求中获取鉴权参数,如果没获取到,跳转到登录页面。

— lua 获取Nignx变量为:ngx.var– 从cookie中获取token值key为token)local token = ngx.var.cookie_token–判断token是否为空,为空跳转if not token then ngx.redirect("http://test.example.com/login", 302)–判断token存在,则根据redis存储格式拼写Tokenelse token = "auth:" .. ngx.var.cookie_tokenend

或者从URL中获取token。

主要依据为前端传送Token存放的位置

local token = ngx.var.arg_token发起鉴权

此处仅连接redis,检查是否存在该token,未做进一步权限鉴别。

local function close_redis(red) if not red then return end local pool_max_idle_time = 10000 –毫秒 local pool_size = 100 –连接池大小 local ok, err = red:set_keepalive(pool_max_idle_time, pool_size) if not ok then ngx.say("close redis error : ",err); endend– 连接redislocal redis = require "resty.redis";local red = redis:new();red:set_timeout(2000)local ok,err = red:connect("127.0.0.1", 6379)if not ok then ngx.say("failed to connect: ", err)end– 请注意这里 auth 的调用过程 这是redis设置密码的local res, err = red:auth("password")if not res then ngx.say("failed to authenticate: ", err)end– redis中若 key 存在返回 1 ,否则返回 0 。local resp, err = red:exists(token) if not resp then ngx.say("get msg error : ", err) return close_redis(red) end if resp == ngx.null then resp = ” end if resp == 0 then– ngx.exit(ngx.HTTP_FORBIDDEN) ngx.redirect("http://test.example.com/login", 302)endclose_redis(red)Nginx配置及完整代码server { listen 80; server_name test.example.com; charset utf-8; autoindex on; autoindex_exact_size on; autoindex_localtime on; location / { lua_code_cache on; rewrite_by_lua_file /usr/local/openresty/nginx/conf/conf.d/redis.lua; error_log /usr/local/openresty/nginx/logs/error.log; root /data/; index index.html; } location /login { alias /data/login; index index.html;}}/usr/local/openresty/nginx/conf/conf.d/redis.lua– 从cookie中获取token值key为token)local token = ngx.var.cookie_token–判断token是否为空,为空跳转if not token then ngx.redirect("http://test.example.com/login", 302)–判断token存在,则根据redis存储格式拼写Tokenelse token = "auth:" .. ngx.var.cookie_tokenendlocal function close_redis(red) if not red then return end local pool_max_idle_time = 10000 –毫秒 local pool_size = 100 –连接池大小 local ok, err = red:set_keepalive(pool_max_idle_time, pool_size) if not ok then ngx.say("close redis error : ",err); endend– 连接redislocal redis = require "resty.redis";local red = redis:new();red:set_timeout(2000)local ok,err = red:connect("127.0.0.1", 6379)if not ok then ngx.say("failed to connect: ", err)end– 请注意这里 auth 的调用过程 这是redis设置密码的local res, err = red:auth("password")if not res then ngx.say("failed to authenticate: ", err)end– redis中若 key 存在返回 1 ,否则返回 0 。local resp, err = red:exists(token) if not resp then ngx.say("get msg error : ", err) return close_redis(red) end if resp == ngx.null then resp = ” end if resp == 0 then– ngx.exit(ngx.HTTP_FORBIDDEN) ngx.redirect("http://test.example.com/login", 302)endclose_redis(red) 寂寞时,想想我的影子,我会在远方给你一个微笑;难过时,

Nginx使用OpenResty+Lua+Redis进行token鉴权

相关文章:

你感兴趣的文章:

标签云: