question_types表插入请求返回403错误,权限验证异常排查
PostgreSQL RLS插入权限返回403,角色验证函数手动查询正常
以下是针对问题的排查方向和解决方案:
1. 类型不匹配:auth.uid()与user_roles.user_id类型不一致
这是最常见的触发原因。Supabase的auth.uid()默认返回UUID类型,如果你的user_roles.user_id是整数类型,函数内的ur.user_id = auth.uid()会因为类型不匹配返回空结果,导致auth_role函数返回false,触发403权限拦截。
修复方案:
- 方案一:将
user_roles.user_id字段类型改为uuid,与auth.uid()的返回类型匹配; - 方案二:修改
auth_role函数,将auth.uid()转换为与user_roles.user_id匹配的类型(假设你在auth.users表中存储了整数类型的用户ID):
CREATE OR REPLACE FUNCTION auth_role(role_name text) RETURNS boolean LANGUAGE plpgsql AS $$ BEGIN RETURN EXISTS( SELECT 1 FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = (SELECT id FROM auth.users WHERE uid = auth.uid()) AND r.name = role_name ); END; $$;
2. authenticated角色无auth_role函数执行权限
如果未给authenticated角色授予auth_role函数的执行权限,函数会执行失败并返回false,导致策略校验不通过。
修复方案:
执行以下SQL语句授予权限:
GRANT EXECUTE ON FUNCTION auth_role(text) TO authenticated;
3. 验证当前请求的用户身份是否正确
确认前端请求携带的JWT对应的用户,确实是你手动查询的<USER_ID>。可以临时修改函数添加日志,验证当前用户:
-- 临时测试用,验证后请改回原函数 CREATE OR REPLACE FUNCTION auth_role(role_name text) RETURNS boolean LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'Current auth.uid(): %', auth.uid(); RETURN EXISTS( SELECT 1 FROM user_roles ur JOIN roles r ON ur.role_id = r.id WHERE ur.user_id = auth.uid() AND r.name = role_name ); END; $$;
执行插入操作后,查看数据库日志中的NOTICE信息,确认当前用户是否与预期一致。
4. 检查RLS策略状态
确认question_types表的RLS确实启用,且策略未被意外修改:
-- 检查RLS是否启用 SELECT relname, rowsecurity FROM pg_class WHERE relname = 'question_types'; -- 查看当前表的所有RLS策略 SELECT * FROM pg_policies WHERE tablename = 'question_types';
内容的提问来源于stack exchange,提问作者Richi
相关产品推荐
相关产品推荐

