openresty钉钉免密登陆

摘要:
appkey=%s&appsecret=%s“,appkey,appsecret))returnres.bodyendlocalfunctionis_dingding_login()--TODO--localmobile={“phone”,“android”,“mobile”,“itouch”,”ipod“,”symbian“,”htc“,”palmos“,”blackberry“,”operamini“,”windowsce“,”nokia“,“fennec”,,“hiptop”,“kindle”,“mot”,,“minimo”,“netfront”,“teleca”}localuserAgent=ngx.req.get_headers().user_AgentuserAgent=字符串。powerfori,vinipairsdoifstring。匹配字符串。matchthenreturnendeendreturnfalsend--将页面重定向到钉的背景地址,并等待另一方调用localfunctionredirect_to_dinging()--TODOlocaluri=“https://oapi.dingtalk.com/connect/oauth2/sns_authorize?signature= '.. 签名..'时间戳='。。时间戳..'&accessKey='。。Appidlocaldata={tmp_auth_code=code}localres,err=postifres==nilorjson.decode['errcode']~=0thenreturnfalse,“未能获取用户uniid”endreturntrue,cjson.decode[“user_info”][“uniid”]endlocalf
--- 本次请求是否应该走钉钉登陆逻辑: zkk
--- 依据UA判定,返回 true 或 false

local luaConfig = require "ding_config"
local hmac = require "resty.hmac"
local cjson = require "cjson.safe"
local http = require "resty.http"
local t_ = require "tool_"
local httpc = http.new()



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 call_back=luaConfig.ding_account.call_back

local function post(url,body)
   
    local http = require "resty.http"
      local httpc = http.new()
      local res, err = httpc:request_uri(url, {
                ssl_verify = false,
                method = "POST",
                body = body,
                headers = {
--                    ['Content-Type']="application/x-www-form-urlencoded",
                    ['Content-Type']="application/json;charset=UTF-8"
        }
      })
    return res,err

end

local 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

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

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



local function is_dingding_login()
    --TODO--
    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"
    }
    local userAgent = ngx.req.get_headers().user_agent
    userAgent = string.lower(userAgent)
    for i, v in ipairs(mobile) do
        if string.match(userAgent, v) and string.match(userAgent, "dingtalk") then
            return true
        end
    end
    return false
end

--- 将页面重定向到钉钉的后台地址,等待对方回调回来
local function redirect_to_dingding()
    --TODO
    local uri="https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid="..appid.."&response_type=code&scope=snsapi_auth&redirect_uri="..call_back
--    print(uri)
    ngx.redirect(uri)
end

local function urlEncode(s)
  s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
  return string.gsub(s, " ", "+")
end

local function temp_code_get_unionid(code)

    --时间戳
    local timestamp = ngx.now()*1000

    --签名计算
    local app_secret = appsecret
    local hmac_sha256 = hmac:new(app_secret, hmac.ALGOS.SHA256)
        if not hmac_sha256 then
            return false,"failed to create the hmac_sha1 object"
        end
    local ok = hmac_sha256:update(tostring(timestamp))
        if not ok then
            return false,"failed to add data"
        end
    local mac = hmac_sha256:final()  -- binary mac
    local signature=ngx.encode_base64(mac)
    if not hmac_sha256:reset() then
        return false,"failed to reset hmac_sha256"
    end
    local sign = urlEncode(signature)
    -- appid 是创建扫码登陆中的appid

    --获取用户信息
    local user_info_url = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature='..sign..'&timestamp='..timestamp..'&accessKey='..appid
    local data={tmp_auth_code = code }
    local res,err=post(user_info_url,cjson.encode(data))
    if res == nil or cjson.decode(res.body)['errcode']~=0 then
        return false,"获取用户unionid失败"
    end
    return true,cjson.decode(res.body)["user_info"]["unionid"]

end

local function unionid_get_userid(unionid)
    --获取全局tooken
    local tooken_ret=get_tooken_glable()
    local g_token=nil
    --{"errcode":0,"access_token":"b7e87fc6cced35ff8f01901c5ae0fa6b","errmsg":"ok","expires_in":7200}
    if cjson.decode(tooken_ret)['errcode'] then
         g_token=cjson.decode(tooken_ret)['access_token']
    else
        return false,"全局token 获取失败"
    end

    --获取用户钉钉userid
    local uid_url=string.format("https://oapi.dingtalk.com/user/getUseridByUnionid?access_token=%s&unionid=%s",g_token,unionid)
    local uid_res,uid_err=get(uid_url)
    --{"errcode":0,"errmsg":"ok","contactType":0,"userid":"083647406924133856"}
    local ding_uid=nil
    if uid_res==nil or cjson.decode(uid_res.body)["errcode"]~=0 then
        return false,"获取钉钉userid失败"
    else
       ding_uid=cjson.decode(uid_res.body)["userid"]
    end

    --获取用户详情
    local user_info_uri=string.format("https://oapi.dingtalk.com/user/get?access_token=%s&userid=%s",g_token,ding_uid)
    local userinfo_res,userinfo_err=get(user_info_uri)
    if userinfo_res==nil or cjson.decode(userinfo_res.body)["errcode"]~=0 then
        return false,"获取用户详情失败"
    else
        local mail=cjson.decode(userinfo_res.body)["email"]
        local mobile=cjson.decode(userinfo_res.body)["mobile"]
        local u_ret={
            mail = mail,
            mobile = mobile,
        }
        return true,u_ret
    end
end


local _M={}
_M.is_dingding_login=is_dingding_login
_M.redirect_to_dingding=redirect_to_dingding
_M.temp_code_get_unionid=temp_code_get_unionid
_M.unionid_get_userid=unionid_get_userid
return _M

免责声明:文章转载自《openresty钉钉免密登陆》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇QT 5.4.1 for Android Windows环境搭建查看Linux声卡基本信息[转载]下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

玩客云安装Armbian

首先,轻扫uboot。阿里云的网卡非常痛苦。如果您没有滑动特定的uboot,则无法驱动它。有三个命令可以滑动uboot,可以按顺序执行:usbstart;fatloadusb01200000u引导。binstorerom_write12000000060000 saveenv三个命令执行后,关闭并重新启动Play Keyun一次,然后再次进入中断模式。再次插...

iTerm2 配色方案(转)

ITerm2配色方案(噢,我的zsh&Powerline)item2.png转到官方网站下载ITerm2,并以全黑色背景打开它。屏幕截图2017-08-01下午5.45.28点。Pngsolarized可以说是目前网络上最流行的配色方案,我个人认为比较这种配色更好。第一种方法:打开iTerm2首选项、配置文件/颜色,然后直接选择Solariz...

AirtestIDE基本功能(二)

文件菜单-相应工具栏上的前四个按钮:新建、打开、保存和另存为新。单击此按钮以选择是否使用创建脚本。air后缀或带有的脚本。py后缀。新脚本将初始化代码,以帮助您从API引入Airtest的各种接口,并自动初始化设备。你可以看到。air脚本文件实际上是一个公用文件夹,其中放置了通过IDE捕获的图像和运行日志。软件关闭时,布局信息将自动保存。(3) 选项-设置设...

C#控件重绘学习(一)

由于需要制作工业控制软件,传统的控制已不能满足实际要求,因此控制的重新绘制迫在眉睫。因为考研花费了很多时间,而C#的学习已经搁浅了很长时间,所以我打算借此机会仔细彻底地研究控件的重新绘制。首先,查看Button的旧背景:namespace:SystemWindows.Forms程序集:System.Windows.FormsButton具有太多属性:例如Ba...

如何快速把ps序列图层建立帧动画?

工具ps1。将序列帧图片加载到ps新建-˃脚本-˃将文件加载到堆栈2中。创建序列帧动画窗口-˃时间线-˃时间线面板的右上菜单-˃从层3创建帧。移除多余的透明画布选择所有层-˃图像-˃剪辑-˃基于透明度4。将图层保存到图片文件-˃脚本-˃将图层保存为文件隐藏白色背景5。导出序列框架文件-˃自动-˃联系人表6存储为png...

安装qmake与环境变量解析

如果你已经有了qmake,可以跳过这里,请看10分钟学会使用qmake。手动安装qmake在手工连编Qt之前,下面这些环境变量必须被设置:QMAKESPEC这个必须设置为你所使用的系统的平台和编译器的组合。当编译完成时,qmake已经可以使用了。这里对添加环境变量时,是在path里头添加,还是new一个变量有点疑惑。而如果是new的话,当我们在为程序添加路径...