lua脚本之钉钉免密登录

时间:2019-06-12
本文章向大家介绍lua脚本之钉钉免密登录,主要包括lua脚本之钉钉免密登录使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

nginx.conf

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}
http {
    resolver 8.8.8.8;
    server {
        listen 8080;
        location / {
            default_type text/html;
            charset utf-8;
            lua_code_cache on;
            #rewrite_by_lua_file /example/rewrite.lua;
            access_by_lua_file /example/root_auth.lua;
            proxy_pass https://tieba.baidu.com/;
        }
        location /auth {
            default_type text/html;
            charset utf-8;
            lua_code_cache on;
            #rewrite_by_lua_file /example/rewrite.lua;
            #access_by_lua_file /example/yidong.lua;
            access_by_lua_file /example/end.lua;
        }
    }
}

end.lua

local http = require "resty.http"
local httpc = http.new()
local mysql = require "resty.mysql"
local cjson = require "cjson"
local b64 = require "base64"
local luaConfig = require("lua_config")


local appid=luaConfig.ding_account.appid
local appsecret=luaConfig.ding_account.appsecret
local AppKey=luaConfig.ding_account.AppKey
local AppSecret=luaConfig.ding_account.AppSecret

local request_uri = ngx.var.request_uri
local request_method = ngx.var.request_method
local dingauth=ngx.var.cookie_dingauth

function isCooike()
    if dingauth ~= nil then
        local dingauth_e=b64.dec(dingauth)
        if cjson.decode(dingauth_e)["cookie_token"]=="3MiOiJuaW5naGFvLm5ldCIsImVE0Mzg5NTU0NDUiLC" then
            ngx.update_time()
            if cjson.decode(dingauth_e)["start_time"] + 5 > ngx.time() then
                local s,e=string.find(request_uri, "?")
                local n_uri=nil
                if s~=nil then
                    n_uri=string.sub(request_uri,1,s-1)
                else
                    n_uri=request_uri
                end
                n_uri=string.gsub(n_uri,"/auth","")
                local u_uri=nil
                if n_uri == "" then
                    u_uri=string.gsub(request_uri,"/auth","/")
                else
                    u_uri=string.gsub(request_uri,"/auth","")
                end
                ngx.redirect(u_uri)
            end
        end
    end
end

function isMobile(userAgent)
    local mobile = {
                "phone", "android", "mobile", "itouch", "ipod", "symbian", "htc", "palmos", "blackberry", "opera mini", "windows ce", "nokia", "fennec",
                "hiptop", "kindle", "mot", "webos", "samsung", "sonyericsson", "wap", "avantgo", "eudoraweb", "minimo", "netfront", "teleca"
            }
    userAgent = string.lower(userAgent)
    for i, v in ipairs(mobile) do
        if string.match(userAgent, v) then
            return true
        end
    end
    return false
end

function get(url)
    local res, err = httpc:request_uri(url,
    {
    ssl_verify = false,
    method = "GET",
    body = "",
    headers = {
       ['Content-Type']="application/json;charset=UTF-8"
         }
    })
    return res,err
end

function post(url,body)
    local res, err = httpc:request_uri(url,
    {
    ssl_verify = false,
    method = "POST",
    body = body,
    headers = {
       ['Content-Type']="application/json;charset=UTF-8"
         }
    })
    return res,err
end

function get_tooken()
    local res,err=get(string.format("https://oapi.dingtalk.com/sns/gettoken?appid=%s&appsecret=%s",appid,appsecret))
    return res.body
end

function dingCallBack(scheme,server_ip,port,l_uri,uir_enb64)
    ding_uri=string.format("https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingoa3fbgkiif8mq9y8jf&response_type=code&scope=snsapi_auth&redirect_uri=%s://%s:%s%s?%s=1",scheme,server_ip,port,l_uri,uir_enb64)
    ngx.redirect(ding_uri)
end

function dingAuth()
tooken_ret=get_tooken()
--{"errcode":0,"access_token":"b7e87fc6cced35ff8f01901c5ae0fa6b","errmsg":"ok","expires_in":7200}
if cjson.decode(tooken_ret)['errcode'] then
    yy_token=cjson.decode(tooken_ret)['access_token']
else
    ngx.say(cjson.encode({status=false,msg="token 获取失败"}))
end
-- 获取用户信息
local user_info_url = string.format("https://oapi.dingtalk.com/sns/get_persistent_code?access_token=%s",yy_token)
local data={tmp_auth_code = code}
local res,err=post(user_info_url,cjson.encode(data))
if cjson.decode(res.body)['errcode']==0 then
    unionid=cjson.decode(res.body)['unionid']
    --深奎
    A_res,A_err=get(string.format("https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s",AppKey,AppSecret))
    if cjson.decode(A_res.body)["errcode"]==0 then
        A_tooken=cjson.decode(A_res.body)["access_token"]
        uid_url=string.format("https://oapi.dingtalk.com/user/getUseridByUnionid?access_token=%s&unionid=%s",A_tooken,unionid)
        local res,err=get(uid_url)
        if cjson.decode(res.body)["errcode"]==0 then
            --u_info_uri=string.format("https://oapi.dingtalk.com/user/get?access_token=%s&userid=%s",A_tooken,cjson.decode(res.body)["userid"])
            --local U_info_res,U_info_err=get(u_info_uri)
            --if cjson.decode(U_info_res.body)["errcode"]==0 then
            --    local mail=cjson.decode(U_info_res.body)["email"]
            --    if mail == nil then
            --        ngx.print("没有权限获取邮箱信息")
            --    elseif mail == "" then
            --        ngx.print("钉钉中没有邮箱信息")
            --    end
            --    ngx.print(mail)
            --else
            --    ngx.print("获取mail失败")
            --end
            local remote_uri=nil
            for k,v in pairs(ngx.req.get_uri_args()) do
                if string.match(k, "DZMSSlIBgrZt6")=="DZMSSlIBgrZt6" then
                    remote_all=b64.dec(string.gsub(k,"DZMSSlIBgrZt6",""))
                    remote_arg=cjson.decode(remote_all)["remote_arg"]
                    remote_uri=cjson.decode(remote_all)["remote_uri"]
                end
            end
            if remote_uri ~= nil then
                remote_uri=string.gsub(remote_uri,"/auth","")
                if remote_uri=="" then
                    remote_uri="/"
                end
                remote_arg_d=cjson.decode(remote_arg)
                remote_arg_d["code"]="1"
                local arg_str=""
                local nb=1
                for key, value in pairs(remote_arg_d) do
                      if nb==1 then
                          arg_str=string.format("?%s%s=%s",arg_str,key,value)
                      else
                         arg_str=string.format("%s&%s=%s",arg_str,key,value)
                      end
                      nb=nb+1
                end
                --ngx.print(string.format("%s%s",remote_uri,arg_str))
                ngx.redirect(string.format("%s%s",remote_uri,arg_str))
            else
                ngx.print("nil")
            end
        else
           ngx.say(cjson.encode({status=false,msg="企业下未找到该用户"}))
            --return cjson.encode({status=false})
        end
    else
        ngx.say(cjson.encode({status=false,msg="全局tooken获取失败"}))
    end
else
    ngx.say(cjson.encode({status=false,msg="获取用户unionid失败"}))
end
end

isCooike()
local userAgent = ngx.req.get_headers().user_agent
local ismobile = isMobile(userAgent)
if "GET"==request_method then
    code = ngx.req.get_uri_args()["code"] or 0
    if code == 0 then
        if ismobile then
            local port=ngx.var.server_port
            local scheme=ngx.var.scheme
            local server_ip="10.10.80.21"
            local s,e=string.find(request_uri, "?")
            local u_a={}
            remote_uri=nil
            if s~=nil then
                remote_uri=string.sub(request_uri,1,s-1)
            end
            u_a["remote_uri"]=request_uri
            u_a["remote_arg"]=cjson.encode(ngx.req.get_uri_args())
            local uir_enb64=b64.enc(cjson.encode(u_a))
            uir_enb64=string.format("DZMSSlIBgrZt6%s",uir_enb64)
            dingCallBack(scheme,server_ip,port,"/auth",uir_enb64)
        else
            ngx.print("是PC端")
        end
    else
        --ngx.print("拿到code")
        dingAuth()
    end
end

base64.lua

base64 = {}

local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
-- You will need this for encoding/decoding
-- encoding
function base64.enc(data)
    return ((data:gsub('.', function(x)
        local r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return b:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end

-- decoding
function base64.dec(data)
    data = string.gsub(data, '[^'..b..'=]', '')
    return (data:gsub('.', function(x)
        if (x == '=') then return '' end
        local r,f='',(b:find(x)-1)
        for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
        return r;
    end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
        if (#x ~= 8) then return '' end
        local c=0
        for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
            return string.char(c)
    end))
end
return base64

lua_config.lua

local config_table={}
config_table.ip='xxx'
config_table.port=xxx
config_table.password='xxx'
config_table.dingding_site={"xxx","xxx"}


local ding_account={}
ding_account["appid"]="xxx"   --免登的id
ding_account["appsecret"]="xxxx"  --免登的secret
ding_account["AppKey"]="xxx"    --有通讯录权限的应用appkey
ding_account["AppSecret"]="xxx"  --有通讯录权限的应用secret
config_table.ding_account=ding_account

return config_table

root_auth.lua

local http = require "resty.http"
local httpc = http.new()
local cjson = require "cjson"
local b64 = require "base64"
local request_method = ngx.var.request_method
--ngx.header['Set-Cookie'] = 'dingauth=cookie; path=/; Expires=' .. ngx.cookie_time(ngx.time() + 1 * 5)
--ngx.print(ngx.var.http_cookie)
local dingauth=ngx.var.cookie_dingauth
local cookie={}
if "GET"==request_method then
    code = ngx.req.get_uri_args()["code"] or 0
    if code == "1" then
        ngx.update_time()
        cookie["start_time"]=ngx.time()
        cookie["cookie_token"]="3MiOiJuaW5naGFvLm5ldCIsImVE0Mzg5NTU0NDUiLC"
        cookie_str=b64.enc(cjson.encode(cookie))
        ngx.header['Set-Cookie'] = string.format('dingauth=%s; path=/; Expires=',cookie_str) .. ngx.cookie_time(ngx.time() + 1 * 5)
    else
        if dingauth == nil then
            ngx.print("没有cookie")
        else
            local dingauth_e=b64.dec(dingauth)
            if cjson.decode(dingauth_e)["cookie_token"]=="3MiOiJuaW5naGFvLm5ldCIsImVE0Mzg5NTU0NDUiLC" then
                local zw="zw"
            end
        end
    end
end

原文地址:https://www.cnblogs.com/zhangkui/p/11009385.html