I have users logging in with an email and password, and I want to check whether a user is logged in, and which user is logged in when trying to access and GET/POST/PUT requests. I havve it set to Application Authentication. It seems like the only way to make sure it is a logged in user and which, is by sending the email and password of that user with every request. Isn’t this a security issue? I shouldn’t have to store their password on the frontend with every request. I have tried reading all the documentation and nothing helps. There was something about putting in the admin api key? But I don’t want the user to have admin privileges, otherwise I would just authenticate each webhook with System instead of Application Authentication. Is there not a way to check using their ID or access token? Basically, unless I put their email and password in the body of the request, I cannot execute the webhook. Help?
Welcome to our forums!
Can you please give me more context on this problem? Is this a Node.js app you’re writing? You shouldn’t be sending passwords, once users are authenticated that’s it. Can you explain what the webhook does, what’s the use case?
Thank you for the warm welcome
Please forgive me, as I am somewhat new to web development and mostly worked in C++ and Java without using databases.
I am using React for my frontend, and MongoDB Realm for my backend, so Node.js is not needed. I will try to explain my problem better:
Currently, I have MongoDB Realm set up create/authenticate users only by email and password. In my frontend, this is done by importing the realm-web SDK and calling Realm.Credentials.emailPassword(email, password). This currently works and I successfully log in with the credentials of a user I have created and am returned some user data such as user.id, user.accessToken, and so on.
Now, I am using MongoDB Realm’s HTTP services under 3rd Party Services on the website. Using this service, I am able to create webhooks that I can use http GET/POST/PUT/etc calls using fetch or axios on my frontend.
In one GET webhook I have, called get_schedule, I have it set to authenticate by Application Authentication. This means that in order for this method to execute, I need to send in a form of authentication with my http.get(“url_to_get_schedule”).
In the documentation, it says I can do this by passing the email and password into the header or body of my request. Having a body cannot be done in a GET request, but it also does not seem to let me add it into the header.
Now, if I configure get_schedule to be a POST method instead of GET, I can pass in the email and password in the body of the request, and the method will now execute. Without this email and password in the body of the request, the method will not execute.
I wanted to see if there is some other way to authenticate this and identifiy the user trying to access the method by passing some sort of token instead of the email and password everytime, as I know storing the password of a user is not secure.
Thanks for the help!
Hi @Callie_Driver and welcome in the MongoDB Community !
As you are building a web app with React + Realm using the Realm Web SDK, you don’t need to use HTTP 3rd party services as there are 2 other & easier options that are safer and already bundled in the Realm Web SDK.
Option 1: https://docs.mongodb.com/realm/web/mongodb/
Directly access the database. Adding a REST API in between is adding an extra layer of communication that isn’t necessary. Basically the idea here is:
- create the Realm app.
- log the user in using any of the auth provider from Realm
- the user object give you access to the collections (See how to allow / limit access with Access Rules)
- you can send any query you like from this point directly to your Atlas cluster from the front-end safely (as access rules handle the limitations of what a user can do - and the SDK the security/token part).
With this trick, you aren’t exposing any email/password to the network. The Realm Web SDK is handling the auth & security for you so you can’t get it wrong. If the user token is expired, the Realm Web SDK should use automatically the refresh token to renew the Auth Token.
This option is actually closer to what you wanted to do: deport some code into the Realm back-end (in your function) and you were trying to call this function through a Realm HTTP Webhook.
You can actually call directly the function without using the HTTP Webhook. You just use - again - directly the user object that you retrieve once you have authenticated the user, and they you can just call the function and retrieve its result - which can be something retrieved from your MongoDB Atlas cluster or something more complexe as your Realm Function can do pretty much anything you want.
To sum up: I would use the first option for its simplicity when you just want to read/write data from your MongoDB Atlas cluster. Easy & simple.
I would use the second option if you have some computation to do or something more complex to implement or if you want to interact with other 3rd party services.
I hope this helps.
Thank you so much @MaBeuLux88! I will look into all of this and hopefully it will make a lot more sense. I do have a couple questions though:
- Does this mean that http service webhooks are obsolete when having access to the Realm Web SDK?
- Would it be better to call a function when doing something such as filtering data from the DB? Or is it better to just call the DB filter straight from the frontend? I am basically trying to understand the boundary between computation and just reading/writing data.
- Yes. You would use HTTP webhooks - in my opinion - only if you were building a website with just Axios (no SDK, etc).
- Filtering can also be achieved at the Access Rules level. I’d also remind that front-end code can be altered by the client so I wouldn’t trust the front-end code too much. At least, I would ensure that whatever the clients sends is controlled by some access rules (in or out) or validated by a function maybe. It’s really up to you how you want to implement this - but yes, you have at least 2 ways to achieve this. Another way would be to use GraphQL that is also available in Realm. But it’s also another layer in the middle (like REST) so my first instinct wouldn’t be in this direction. Again, it’s just my opinion. With my nose in your project, it’s possible to some constraints could make me think differently.
If you really want something even more custom and flexible, you could add a node.js backend in between and use the Realm Node.js SDK and drop the Web SDK from your front-end.
But then it’s down to you to secure the back-end (node) / frond-end (web) communication.