I would like to be able to access data from the database within an Action Handler in Hasura. Is the best approach:
to make a GraphQL query to the API exposed by Hasura; or
use a client, like Prisma, to read from the db directly?
I'm not sure there is a best approach. Personally, I use the API exposed by Hasura in action handlers. I've chosen to do this because:
I like the API exposed by Hasura.
I like the access controls that Hasura layers over top of the DB (although you could just use the admin account, too).
The API can be used to generate TypeScript types, which I use in the action handler. This means that I can confidently change the database schema or Hasura API and then see where my other code fails.
I have thought many times about your question though, because there is something a little odd about calling back into Hasura to handle a Hasura action. But the reasons mentioned above are substantial gains in my opinion, so I've stuck with this approach.
Related
So currently in the project we have a collection of documents that don't require authentication to be read. They are write/update protected, but everyone can read.
What we are trying to prevent is that someone looks at the firebase endpoints and somehow manages to scrape the entire collection in json format (if this is even possible). The data is public, but I want it only to be accessible from our website.
One of the solutions we could think of was SSR (we are already using Next.js), but implementing SSR just for this reason doesn't seem very enticing.
Any suggestions would be appreciated.
EDIT:
Let me rephrase a little bit.
From what you see in the network tab, is it possible to forge/create a request to Firestore and get the entire collection instead of just the 1 document that was intended?
The best solution in your case is SSR. I know, it could sound as not enticing, but well, let's reason on when we should use SSR, then. In your use case, there is an important requirement: security. I think this is already a strong enough reason to justify the usage of SSR.
Also, creating an ad hoc service account for the next.js app, and securing the data with custom rules that allow the read of your data only to that service account, would only improve the overall security level.
Last: reading the data server side should make your site work a little faster, even if it would be difficult to notice, because we are talking about milliseconds. Notice that your page, as it is now, will need to be loaded, before the request to Firebase could be sent. This is adding a small delay. If the data is loaded server side, the delay is not added.
is it possible to forge/create a request to Firestore and get the entire collection instead of just the 1 document that was intended?
If you want to limit what people can request from a collection, you're looking for security rules. The most common model there is some form of ownership-based access control or role-based access control, but both of those require some way of identifying the user. This could be anonymously (so without them entering credentials), but it'd still be a form of auth.
If you don't want to do that, you can still control how much data can be gotten through the API in one go. For example, if you in the security rules allow get but not list, the user can only request a document once they know its ID. Even if you allow list, you can control in rules what queries are allowed.
I think one approach could be writing a Cloud Function that retrieves this public data using the admin SDK. Then, you could set a rule that nobody can read those documents. This means that only your Cloud Function with the admin SDK will have access to those documents.
Finally, you could set up AppCheck for that specific Cloud Function, this way, you ensure that the request is coming from your client app only.
https://firebase.google.com/docs/app-check
I'm trying to make a simple React app that uses Cloud Firestore for user auth and storing data; something that I could serve using heroku or something like that.
I'm running into trouble with enabling a user to delete their account (and associated data), as Firestore tells me that it's a bad idea to delete collections from the client side. Here's what they say:
Deleting a collection requires coordinating an unbounded number of individual delete requests. If you need to delete entire collections, do so only from a trusted server environment. While it is possible to delete a collection from a mobile/web client, doing so has negative security and performance implications.https://firebase.google.com/docs/firestore/manage-data/delete-data
While I might be able to delete the document connected with the user's account, this suggests that I can't really delete the sub-collections under that document.
So what would be a good way of automatically removing both the user document and user sub-collections? Can I achieve this through my react code? If not, is there a relatively easy way to do it without building a fancy back end?
Well, the documentation never says that this is not possible, just not recommended.
This makes sense if you consider that if you want to delete everything, including documents from subcollection, you would have to create a logic that will do this one by one, which is a very read intensive process and all of this data processing happening in your webapp is not a good practice, it might slow your app down or even block functionality while this process is occuring, etc.
What I would recommend for you is to follow the recommendations of Firestore itself, which is to create a Callable Function that will perform this actions for you, all processing will be done by that function and this will not degrade your app performance, you can find more details in this documentation.
Titlte says it all I think.
I have encountered both and don't know which one I should use between $_SESSION['Auth'] and $this->Authentication->getIdentity(). Is one safer than the other ?
Thank you,
Simon
With CakePHP you should always use the abstracted APIs to access any superglobal data like $_POST, $_COOKIE, $_SESSION, etc..
This is advised for a multitude of reasons that depend on the specific situation, but generally it kinda touches the principle of dependency inversion, and decoupling in general, eg. your code should depend on abstractions, not concretes, then for example implementations can change without breaking your application. And while the session object, the request object, or the authentication component aren't interfaces, they still abstract the access to the underlying data (the concrete so to speak).
Something where the need for this would apply generally, would be testing, except for the CakePHP session object, which must write the data to the $_SESSION superglobal internally, other superglobals like $_GET, $_POST, $_COOKIE, etc. are not being populated if you use the API provided by CakePHP, instead the data is written into the request object, which exposes the data via its own API. So if you were for example to access $_POST directly in your code, and then pass POST data in a test like $this->post('/url', $postData), your code wouldn't see the data, as it would directly land in the request object instead of the $_POST superglobal.
As far as the authentication example specifically goes, the authentication middleware could have obtained the identity with data from who knows where, the session, cookies, tokens, etc., and likewise it could persist the identity anywhere, the session, cookies, etc, the inner layers of your application shouldn't have to care about such implementation details, they obtain the identity via the component, or from the request object, and that's it, they don't need to know anything else, then you can easily change how authentication is handled without breaking the rest of your application.
I want to be able to manage users in contenful, every user has some data (files, text, etc) that should only be able te be accessed by this specific authenticated user.
In firebase for example this would be possible by using database rules, but would something similar be possible in contentful?
ps: I try to avoid writing custom backend for this.
As you say you would not like to write custom backend code.
If you are calling the Contentful API on the client side instead of a backend server calling Contentful, the Authorisation keys will be exposed allowing anyone to scan through all the Contentful User data.
It may not be the ideal CMS for your use case.
For example, I need to validate email during registration process (check, if it already exists in database). In this case i have no need to store any data.
Should i utilize flux way and call server side (nodejs) api through Actions or just call server side api right from the registration form component?
Since you are calling the server I would go through actions , receive the answer call dispatch and put it in a simple store where your email status become "verified" instead of "unverified".
Store is not only storing things but keeping your data workflow states updated.
Just my opinion but I would do that. It will be cleared to do like that to master your data flow in the future.