Apex对接钉钉免登

前提

  1. 打通数据库服务器访问钉钉的网络

  2. Oracle ACL是否放行

  3. Wallet 是否添加钉钉证书

  4. Apex INTERNAL 工作区是否添加 Wallet 路径

  5. 测试请求

    1
    2
    3
    4
    
    select   APEX_WEB_SERVICE.make_rest_request(
                    p_url => 'https://developers.dingtalk.com/',
                    p_http_method => 'GET')
    from dual;
    
  6. 钉钉关键信息APPKEY,APPSECRET,AGENT_ID,corpId (向本公司钉钉管理员建H5应用索要)

  7. 钉钉JS dingtalk.open.js

步骤

  1. 新建应用

  2. 将 dingtalk.open.js 导入应用的静态文件中得到 #WORKSPACE_IMAGES#dingtalk.open.js

  3. 新建全局页项 DINGDING_CODE,DINGDING_ACCESS_TOKEN 权限都是设置为 无限制

  4. 共享组件»应用程序处理中创建一个全局的Ajax回调 名字GET_DINGDING_PD_ACCESS_TOKEN 权限设置为不需要授权

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    Declare
        l_code      varchar2(100) := apex_application.g_x01; 
        l_appkey    varchar2(30)  := 'din0';  -- 前提6中的 APPKEY
        l_appsecret varchar2(70)  := 'O5Gg5P'; -- 前提6中的 APPSECRET
        l_email     varchar2(100) := null ;
        l_clob      clob;
    Begin
        if l_code is not null then
            :DINGDING_CODE := l_code;  -- 
            apex_web_service.g_request_headers(1).name := 'Content-Type';
            apex_web_service.g_request_headers(1).VALUE := 'application/json';
            l_clob := APEX_WEB_SERVICE.make_rest_request(
                    p_url => 'https://oapi.dingtalk.com/gettoken',
                    p_http_method => 'GET',
                    p_parm_name =>apex_util.string_to_table('appkey:appsecret'),
                    p_parm_value =>apex_util.string_to_table(l_appkey || ';' || l_appsecret, p_separator=>';')
                );
            apex_json.parse(l_clob);
            if apex_json.does_exist(p_path => 'access_token') then
                :DINGDING_ACCESS_TOKEN := apex_json.get_varchar2(p_path => 'access_token');
                apex_json.open_object();
                apex_json.close_object();
            end if;
            apex_json.open_object();
            apex_json.close_object();
        end if;
    End;
    
  5. 新建钉钉登录中转页(page_id 9990)

  6. 将默认登录页9999中的页别名 剪切 到中转页

  7. 在中转页 JavaScript 区域文件URL填充 #WORKSPACE_IMAGES#dingtalk.open.js 函数和全局变量声明

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    if (dd.env.platform === "notInDingTalk") {
    alert('抱歉请在钉钉登录');
    } else {
        dd.ready(function () {
            // dd.ready参数为回调函数,在环境准备就绪时触发,jsapi的调用需要保证在该回调函数触发后调用,否则无效。
            dd.runtime.permission.requestAuthCode({
    
                corpId:"ding46", // 前提 6中的corpId
                onSuccess: function (result) {
                    apex.server.process(
    
                         "GET_DINGDING_PD_ACCESS_TOKEN", // 保持和3中的名字一致
                        { 'x01': result.code },
                        {
                            success: function (data) {
                             //   alert(data)
                                window.location ='f?p='+&APP_ID.+':1:'+&APP_SESSION.
                            }
                        }
                    );
                },
                onFail: function (err) {
                    alert('抱歉钉钉登录失败');
                }
    
            });
        });
    }
    
  8. 自定义认证方案pl/sql 会话过程名无效 TOKEN_INVALID_SESSION_DINGDING_1

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    
    PROCEDURE TOKEN_INVALID_SESSION_DINGDING_1
            IS
            l_access_token varchar2(50)  := :DINGDING_ACCESS_TOKEN ;
            l_userid       varchar2(50)  := null ;
            l_email        varchar2(100) := null ;
            l_clob         clob;
    
            BEGIN
                -- get code
                -- 获取access_token
                -- 通过免登授权码和access_token获取用户的userid
    
                apex_debug.warn('+++++++++++l_access_token+++++++++++>');
                apex_debug.warn(l_access_token);
                apex_debug.warn('<+++++++++++');
    
                if l_access_token is not null then
                    l_clob := APEX_WEB_SERVICE.make_rest_request(
                            p_url => 'https://oapi.dingtalk.com/user/getuserinfo',
                            p_http_method => 'GET',
                            p_parm_name =>apex_util.string_to_table('access_token:code'),
                            p_parm_value =>apex_util.string_to_table(l_access_token || ';' || :DINGDING_CODE, p_separator=>';')
                        );
                    apex_debug.warn('------------->');
                    apex_debug.warn(l_clob);
                    apex_debug.warn('<-------------');
                    apex_json.parse(l_clob);
                    apex_debug.warn('+++++++++++l_code+++++++++++>');
                    apex_debug.warn(l_clob);
                    apex_debug.warn('<+++++++++++');
                    if apex_json.does_exist(p_path => 'userid') then
                        l_userid := apex_json.get_varchar2(p_path => 'userid');
                      --  :CREATED_BY_NAME :=apex_json.get_varchar2(p_path => 'name'); --取姓名
                        --  :DINGDING_USERID := l_userid;
                        sys.dbms_output.put_line('l_userid' || ' - ' || l_userid);
                        APEX_DEBUG.WARN('l_userid' || ' - ' || l_userid);
                    else
                          apex_json.open_object();
    
                apex_json.write('l_clob', l_clob);
                apex_json.close_object();
                    end if;
                end if;
                /*
                        -- 用户8位工号
                        if l_userid is not null then
                            l_clob := APEX_WEB_SERVICE.make_rest_request(
                                    p_url => 'https://oapi.dingtalk.com/user/get',
                                    p_http_method => 'GET',
                                    p_parm_name =>apex_util.string_to_table('access_token:userid'),
                                    p_parm_value =>apex_util.string_to_table(l_access_token || ';' || l_userid, p_separator=>';')
                                );
                            apex_json.parse(l_clob);
                            if apex_json.does_exist(p_path => 'jobnumber') then
                                l_email := apex_json.get_varchar2(p_path => 'jobnumber');
                                sys.dbms_output.put_line('l_email' || ' - ' || l_clob);
                                APEX_DEBUG.WARN('l_email' || ' - ' || l_clob);
                            end if;
                        end if;
    
                */
    
                if l_userid is not null then
                    -- login
                    if l_userid='03' then l_userid:='02'; end if; -- 模拟账号
                    apex_authentication.post_login(l_userid,
                                                   null, true);
                end if;
            End;
        ```
    
Licensed under CC BY-NC-SA 4.0
最后更新于 2025-12-03 14:35
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计