当前位置 主页 > 服务器问题 > nginx问题汇总 >

    在Nginx中增加对OAuth协议的支持的教程(3)

    栏目:nginx问题汇总 时间:2018-10-25 16:33

    在运行这个伟大过程的同时,我构建了一个小的批处理脚本来自动化这个过程的主要步骤,你可以在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