You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL 15中pgjwt签名函数调用报错问题排查

问题原因与解决方法

这个问题的核心是参数类型不匹配:pgjwt提供的sign函数接受的第一个参数类型是json或jsonb,而你动态构建payload时,大概率直接生成了text类型的字符串,PostgreSQL无法自动隐式转换该类型去匹配sign函数的参数要求,因此抛出“函数不存在”的错误;硬编码场景下你可能显式声明了json/jsonb类型(比如用::json强制转换),所以能正常运行。

解决步骤

  1. 确保动态payload为json/jsonb类型
    错误示例(动态拼接字符串生成text类型payload):

    CREATE OR REPLACE FUNCTION generate_jwt(p_role text, p_secret text)
    RETURNS text AS $$
    DECLARE
        v_payload text;
    BEGIN
        v_payload := '{"sub": "' || p_role || '", "exp": ' || extract(epoch from now() + interval '1 hour') || '}';
        RETURN pgjwt.sign(v_payload, p_secret); -- text类型参数不匹配
    END;
    $$ LANGUAGE plpgsql;
    

    正确写法(用json_build_object直接生成json类型):

    CREATE OR REPLACE FUNCTION generate_jwt(p_role text, p_secret text)
    RETURNS text AS $$
    DECLARE
        v_payload json;
    BEGIN
        v_payload := json_build_object(
            'sub', p_role,
            'exp', extract(epoch from now() + interval '1 hour')
        );
        RETURN pgjwt.sign(v_payload, p_secret);
    END;
    $$ LANGUAGE plpgsql;
    

    若坚持字符串拼接,必须强制转换类型:

    v_payload := ('{"sub": "' || p_role || '", "exp": ' || extract(epoch from now() + interval '1 hour') || '}')::json;
    
  2. 验证函数签名匹配
    执行以下命令查看pgjwt的sign函数参数类型:

    SELECT proname, proargtypes::regtype[] 
    FROM pg_proc 
    WHERE proname = 'sign' 
      AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'pgjwt');
    

    结果会显示它的参数为json, text或jsonb, text,需确保第一个参数是这两种类型之一。

  3. 规避SQL注入风险
    禁止用字符串拼接方式构建payload,这会引入注入隐患。使用json_build_object/jsonb_build_object既能保证类型正确,又能安全生成JSON对象。

内容的提问来源于stack exchange,提问作者ziazo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:45:56