Closed rijkvanzanten closed 2 years ago
cc @nitwel
Interesting idea, for the moment I was more thinking towards doing the authentication at the point where the request gets upgraded then persisting that for the duration of the open socket. That way opening the socket can take advantage of the regular api endpoint api token logic then using the resulting accountability object to access all services to take advantage of the build in authorization there.
Altough i do just realize that that wont work for the events pushed by "actions" unless i explicitly fetch the object also 🤔
@rijkvanzanten I implemented authentication! In a bit of a limited form but for static user tokens it works 😄
Altough i do just realize that that wont work for the events pushed by "actions" unless i explicitly fetch the object also 🤔
Curious to learn more! Are you currently "just" sending through the exact payload from the hook, or are you fetching the modified item fresh, and treating it as a read
operation? I believe that's what GraphQL does in its Subscriptions too 🤔
I was considering doing an extra fetch on the update action to always return the full object but for now im just passing on the hook payload as-is. I decided to indeed treat all subscribe
requests as read
operations (doing a single read with accountability before registering the actual message hooks). Optimally i would love to check the permissions before sending any object over the wire but this seemed most practical to start with.
Yeah! I was thinking you could treat the hooks as a trigger to execute the read request the user asked for in the initial subscription. That way, we should be able to rely on all the regular permissions and services magic that already exists.
That does make me wonder though: Would you subscribe to single items, or could you also subscribe to a collection? Like every time an item is deleted, give me the most recent 50 items?
I think having the option of subscribing to any mutations on a collection is quite valuable already (at least for my usecase) but definitely considering extending that with way to subscribe to a single primary key and/or multiple keys too. And eventually subscribing to a query would be awesome but that would definitely require some thinking on how to implement, im not a big fan of blindly sending the query results on each action fired as none of the items contained might have changed.
but definitely considering extending that with way to subscribe to a single primary key and/or multiple keys too
Alternatively, you could provide a "filter" object when you subscribe. That way, you could say: "Send me an update when articles
changes, but only when published
= true
". This in turn also allows subscribing to individual items, as you could say "Let me know when article with ID = 5 is deleted"
im not a big fan of blindly sending the query results on each action fired as none of the items contained might have changed.
Very good point. And you could always just make a "regular" request to refresh that data set if your app needs it.
I found a novel way of running the websocket upgrade request through the express app! This way i can directly take advantage of the directus built-in middlewares instead of trying to copy-paste the logic form the directus core :)
That's awesome!!
A connected websocket client is stateful right? Maybe we could add an "authorize" type that will set the access token of the current session. That way, we could rely on the access token of the session to check against the permissions w/ the regular permissions/authorization middleware before responding over the socket with the requested data 🤔