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

2019-10-17 20:14:03刘景俊

    if not access_token then
        -- 跟踪用户访问,用于透明的重定向
        ngx.header["Set-Cookie"] = "SGRedirectBack="..nginx_uri.."; path=/;Max-Age=120"

        -- 重定向到 /oauth , 获取权限
        return ngx.redirect("internal-oauth:1337/oauth?client_id="..app_id.."&scope=all")
    end
end

此时在Lua脚本中,应该已经有了一个可用的access_token。我们可以用来获取任何请求需要的用户信息。在本文中,返回401表示没有权限,403表示token过期,并且授权信息用简单数字打包成json响应。

-- 确保用户有访问web应用的权限
-- internal-oauth:1337/accessible
local res = ngx.location.capture("/_user", {args = { access_token = access_token } } )
if res.status ~= 200 then
    -- 删除损坏的 token
    ngx.header["Set-Cookie"] = "SGAccessToken=deleted; path=/; Expires=Thu, 01-Jan-1970 00:00:01 GMT"

    -- 如果 token 损坏 ,重定向 403 forbidden 到 oauth
    if res.status == 403 then
        return ngx.redirect("https://seatgeek.com/oauth?client_id="..app_id.."&scope=all")
    end

    -- 没有权限
    ngx.status = res.status
    ngx.say("{"status": 503, "message": "Error accessing api/me for credentials"}")
    return ngx.exit(ngx.HTTP_OK)
end

 

现在,我们已经验证了用户确实是经过身份验证的并且具有某个级别的访问权限,我们可以检查他们的访问级别,看看是否同我们所定义的任何当前端点的访问级别有冲突。我个人在这一步删除了SGAccessToken,以便用户拥有使用不同的用户身份登录的能力,但这一做法用不用由你决定。

local json = cjson.decode(res.body)
-- Ensure we have the minimum for access_level to this resource
if json.access_level < 255 then
    -- Expire their stored token
    ngx.header["Set-Cookie"] = "SGAccessToken=deleted; path=/; Expires=Thu, 01-Jan-1970 00:00:01 GMT"

    -- Disallow access
    ngx.status = ngx.HTTP_UNAUTHORIZED
    ngx.say("{"status": 403, "message": "USER_ID"..json.user_id.." has no access to this resource"}")
    return ngx.exit(ngx.HTTP_OK)
end

-- Store the access_token within a cookie
ngx.header["Set-Cookie"] = "SGAccessToken="..access_token.."; path=/;Max-Age=3000"

-- Support redirection back to your request if necessary
local redirect_back = ngx.var.cookie_SGRedirectBack
if redirect_back then