在运行这个伟大过程的同时,我构建了一个小的批处理脚本来自动化这个过程的主要步骤,你可以在gist on github上找到它。
在我意识到这个过程可以被脚本化之前仅仅花费了90个nginx包的构建时间。
全部OAuth
现在可以测试并部署嵌入Nginx的Lua脚本了,让我们开始Lua编程。
nginx-lua模块提供了一些辅助功能和变量来访问Nginx的绝大多数功能,显然我们可以通过access_by_lua中该模块提供的指令来强制打开OAuth认证。
当使用*_by_lua_file指令后,必须重载nginx来使其起作用。
我用NodeJS为SeatGeek创建了一个简单的OAuth2提供者类。这部分内容很简单,你也很容易获得你是通用语言的响应版本。
接下来,我们的OAuth API使用JSON来处理令牌(token)、访问级别(access level)和重新认证响应(re-authentication responses)。所以我们需要安装lua-cjson模块。
复制代码 代码如下:# install lua-cjson
if [ ! -d lua-cjson-2.1.0 ]; then
tar zxf lua-cjson-2.1.0.tar.gz
fi
cd lua-cjson-2.1.0
sed 's/i686/x86_64/' /usr/share/lua/5.1/luarocks/config.lua > /usr/share/lua/5.1/luarocks/config.lua-tmp
rm /usr/share/lua/5.1/luarocks/config.lua
mv /usr/share/lua/5.1/luarocks/config.lua-tmp /usr/share/lua/5.1/luarocks/config.lua
luarocks make
我的OAuth提供者类使用了query-string来发送认证的错误信息,我们也需要在我们的Lua脚本中为其提供支持:
复制代码 代码如下:local args = ngx.req.get_uri_args()
if args.error and args.error == "access_denied" then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("{\"status\": 401, \"message\": \""..args.error_description.."\"}")
return ngx.exit(ngx.HTTP_OK)
end
现在我们解决了基本的错误情况,我们要为访问令牌设置cookie。在我的例子中,cookie会在访问令牌过期前过期,所以我可以利用cookie来刷新访问令牌。
复制代码 代码如下:local access_token = ngx.var.cookie_SGAccessToken
if access_token then
ngx.header["Set-Cookie"] = "SGAccessToken="..access_token.."; path=/;Max-Age=3000"
end
现在,我们解决了错误响应的api,并储存了access_token供后续访问。我们现在需要确保OAuth认证过程正确启动。下面,我们想要:
如果没有access_token已经或将要存储,开启OAuth认证 如果query string的参数中有OAuth访问代码(access code),使用OAuth API检索用户的access_token 拒绝使用非法访问代码用户的请求阅读nginx-Lua函数和变量的相关文档可以解决一些问题,或许还能告诉你访问特定请求/响应信息的各种方法。
此时,我们需要从我们的api接口获取一个TOKEN。nginx-lua提供了ngx.location.capture方法,支持发起一个内部请求到redis,并接收响应。这意味着,我们不能直接调用类似于http://seatgeek.com/ncaa-football-tickets,但我们可以用proxy_pass把这种外部链接包装成内部请求。
我们通常约定给这样的内部请求前面加一个_(下划线), 用来阻止外部直接访问。
复制代码 代码如下:-- 第一步,从api获取获取token
if not access_token or args.code then
if args.code then
-- internal-oauth:1337/access_token