PL/SQL调用APEX oauth_authenticate获取OAuth2令牌报ORA-20987错误怎么解决?
问题原因与解决方案
错误原因
该错误是APEX内置的严格模式JSON解析器处理OAuth2令牌接口返回值时触发的,解析器要求返回内容必须是标准JSON格式,但你实际得到的响应不是合法JSON(可能是纯文本报错、HTML错误页面、包含未加引号的布尔/空值等非标准JSON结构)。
相同参数Postman调用成功、PL/SQL调用失败的核心差异原因:
- 你的PL/SQL代码本身存在参数错误:
client_id赋值末尾多了一个多余的英文逗号,你定义的是client_id varchar(255) := 'client_id,';,实际传入接口的client_id值带了逗号,和Postman里使用的正确参数不一致,导致接口返回非JSON格式的报错信息 - 其他可能的差异:PL/SQL执行环境缺少访问目标端点的ACL出站权限、非APEX会话下调用时请求头缺少必要信息,导致接口返回非JSON的错误响应
解决步骤
- 首先修复代码里的参数错误,删掉client_id末尾多余的逗号,修正后代码如下:
client_id varchar(255) := 'client_id'; client_sec varchar(255) := 'client_sec'; endpoint varchar(255) := 'http://localhost:3000/ords/restw/oauth/token'; begin apex_web_service.oauth_authenticate( p_token_url => endpoint, p_client_id => client_id, p_client_secret => client_sec ); end; /
- 若修正参数后仍报错,先手动打印接口原始返回值确认响应格式,用以下代码调试:
declare client_id varchar(255) := 'client_id'; client_sec varchar(255) := 'client_sec'; endpoint varchar(255) := 'http://localhost:3000/ords/restw/oauth/token'; v_resp clob; begin v_resp := apex_web_service.make_rest_request( p_url => endpoint, p_http_method => 'POST', p_username => client_id, p_password => client_sec, p_parm_name => apex_string.string_to_table('grant_type'), p_parm_value => apex_string.string_to_table('client_credentials') ); dbms_output.put_line('接口返回内容:'||v_resp); end; /
- 若返回内容提示权限不足,需要为执行PL/SQL的数据库用户配置访问localhost:3000的ACL出站权限,示例配置代码:
begin dbms_network_acl_admin.append_host_ace( host => 'localhost', lower_port => 3000, upper_port => 3000, ace => xs$ace_type( privilege_list => xs$name_list('connect', 'resolve'), principal_name => '你的数据库用户名', principal_type => xs_acl.ptype_db ) ); commit; end; /
- 若你是在SQL Developer等非APEX会话环境执行代码,需要先初始化APEX上下文,在业务逻辑前添加以下内容:
begin apex_session.create_session( p_app_id => 你的APEX应用ID, p_page_id => 1, p_username => '你的APEX用户名' ); -- 后续调用oauth_authenticate的业务逻辑 end; /
内容的提问来源于stack exchange,提问作者BojanKosta
相关产品推荐
相关产品推荐

