Comments (8)
It works for me; are you sure that changing pgStrictFunctions
to false definitely solves it? It seems to me that it's probably an RLS policy issue. I don't think subscriptions support JWTs right now - you have to add your own websocketMiddlewares
to process request headers.
Here's how I checked:
schema:
create table people (
id serial primary key,
name text not null
);
create or replace function tg_notify() returns trigger as $$
begin
perform pg_notify(tg_argv[0], json_build_object('__node__', json_build_array(tg_argv[1], new.id))::text);
return NEW;
end;
$$ language plpgsql volatile;
create trigger _500_notify after insert on people for each row execute procedure tg_notify('postgraphile:people:insert', 'people');
server.js:
const http = require("http");
const { postgraphile, makePluginHook } = require("postgraphile");
const {
default: PostGraphileSupporter
} = require("@graphile/plugin-supporter");
const pluginHook = makePluginHook([PostGraphileSupporter]);
http
.createServer(
postgraphile("issue1", "public", {
graphiql: true,
pluginHook,
simpleSubscriptions: true,
graphileBuildOptions: {
pgStrictFunctions: true
}
})
)
.listen(3495);
Create through GraphiQL:
Record shows up in Playground:
from issues.
@benjie Can you tell more about handling RLS policy with websocketMiddlewares
?
from issues.
Sure, read this:
https://www.graphile.org/postgraphile/subscriptions/#enabling-with-an-express-app
If you have more questions I’m going to need to know more about your app and how you have configured it / how you are expecting the user to be authenticated / etc.
from issues.
@benjie This is my configuration
In database i used RSL. If JWT cannot be used in Subscription like Query/Mutation, I do not know how to make the relatedNode not null. You talk about websocketMiddlewares
but I havent understood how to solve it.
{
pluginHook,
simpleSubscriptions: true,
graphiql: true,
graphileBuildOptions: {
pgStrictFunctions: true,
},
pgDefaultRole: 'guest',
dynamicJson: true,
jwtSecret: JWT_SECRET,
jwtPgTypeIdentifier: 'tocu_schema.jwt_token',
exportGqlSchemaPath:
process.env.NODE_ENV === 'production' ? './schema.graphql' : undefined,
classicIds: true,
setofFunctionsContainNulls: false,
},
CREATE SEQUENCE tocu_schema.person_id_seq;
CREATE TABLE tocu_schema.person (
id int NOT NULL DEFAULT NEXTVAL('tocu_schema.person_id_seq') PRIMARY KEY,
name text not null CHECK (char_length(name) < 80),
username citext UNIQUE CHECK (username is not null and username ~* '^[a-z](?:[a-z\d]|-(?=[a-z\d])|\.(?=[a-z\d])){2,38}$'),
password text,
role tocu_schema.role_enum not null default 'customer',
vip boolean not null default false,
mobile_phone text UNIQUE check(mobile_phone ~ '^(030|031|032|033|034|035|036|037|038|039|050|051|052|053|054|055|056|057|058|059|070|071|072|073|074|075|076|077|078|079|080|081|082|083|084|085|086|087|088|089|090|091|092|093|094|095|096|097|098|099)\d{7}$'),
mobile_phone_verified boolean DEFAULT FALSE,
fb_id text unique check (fb_id ~ '^[0-9\.]+$'),
fb_username text unique check(fb_username ~ '^[a-z\d.]{5,}$'),
unread_notifications_count integer not null default 0,
last_notification_id integer references tocu_schema.notification(id) on delete restrict,
note text,
created_by integer references tocu_schema.person(id),
updated_by integer references tocu_schema.person(id),
created_at timestamp not null DEFAULT now(),
updated_at timestamp not null DEFAULT now(),
search_words tsvector
);
CREATE INDEX person_idx ON tocu_schema.person USING GIN(search_words, updated_at, mobile_phone);
comment on table tocu_schema.district is E'@omit create';
grant select on table tocu_schema.person to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor;
grant insert, update on table tocu_schema.person to boss, manager, sales, support_online;
grant usage on sequence tocu_schema.person_id_seq to boss, manager, sales, support_online;
-- Row security
alter table tocu_schema.person enable row level security;
create policy select_me on tocu_schema.person for select to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor
using (id = current_setting('jwt.claims.person_id')::integer);
create policy select_customer on tocu_schema.person for select to boss, manager, sales, support_online
using (true);
create policy insert_person on tocu_schema.person for insert to boss, manager, sales, support_online
with check (created_by = current_setting('jwt.claims.person_id')::integer);
create policy update_me on tocu_schema.person for update to boss, manager, sales, support_online, customer, shipper, cashier, warehouse_manager, warehouse_staff, visitor
using (id = current_setting('jwt.claims.person_id')::integer);
create policy update_customer on tocu_schema.person for update to boss, manager, sales, support_online
using (true);
create or replace function tocu_schema.notification_added_notify()
returns trigger as $$
begin
perform pg_notify(
'postgraphile:notification_added:' || new.id,
json_build_object(
'__node__', json_build_array('people', new.id)
)::text
);
return new;
end;
$$
LANGUAGE plpgsql strict SECURITY DEFINER;
create trigger notification_added_notify_trigger after update of last_notification_id on tocu_schema.person
for each row EXECUTE PROCEDURE tocu_schema.notification_added_notify();
from issues.
Ah; I see the issue. You have:
json_build_object(
'__node__', json_build_array('people', new.id)
)::text
but your table is called person
not people
, so the nodeId you reference does not point to anything. I thought JWT should automatically work! The middlewares are only necessary for sessions/other forms of auth.
from issues.
@benjie I think table name = person
and node name = people
is right, it is not a issue.
If I comment remove line pgDefaultRole: 'guest'
, relatedNode return data object. If pgDefaultRole is guest
return null.
{
pluginHook,
simpleSubscriptions: true,
graphiql: true,
graphileBuildOptions: {
pgStrictFunctions: true,
},
// pgDefaultRole: 'guest',
dynamicJson: true,
jwtSecret: JWT_SECRET,
jwtPgTypeIdentifier: 'tocu_schema.jwt_token',
exportGqlSchemaPath:
process.env.NODE_ENV === 'production' ? './schema.graphql' : undefined,
classicIds: true,
setofFunctionsContainNulls: false,
},
return
And I found Authorization bearer token key in the header is not effective when using Subscription.
from issues.
Ah okay; maybe we don’t yet support JWT via subscriptions. I’ll take a look.
Odd that we use the plural of the table name. That must be a legacy thing.
from issues.
v0.8.3 of @graphile/supporter
supports JWT in both the HTTP headers and in the initial websocket payload 👍
from issues.
Related Issues (8)
- TS definitions for `@graphile/supporter` HOT 3
- Allow specifying the cost limits per request HOT 3
- Introduce smart comments to allow hinting at the cost of an unlimited query of a table HOT 1
- Unable to enable pro plugin using docker image HOT 2
- peerDependency on postgraphile missing in @graphile/pro HOT 1
- Graphile Pro: overrideOptionsForRequest defaultPaginationCap is not taken into account HOT 4
- When inside of a resolver for a subscription, allow `selectGraphQLResultFromTable` to use the read only connection string HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from issues.