Temporary User Accounts: MongoDB vs Redis - node.js

I'm developing an application with NodeJS, ExpressJS and MongoDB. Currently I'm working on the user registration process. I would like to store the user account temporary until the user has verified his email address, if the email address is not verified within a certain amount of time, I would like to remove the temporary account.
Currently I've following two ideas to solve the issue:
Creating a mongoose TempUserModel (besides the UserModel), i.e. if the user does the registration a temp user will be created, as soon as the user verified his email address, the temporary user account will be copied to the real Users collection. Some cronjobs could be setup to delete not verified user accounts after a certain amount of time (probably there are better solutions to let expire a mongodb record)
Setup redis to store the temporary user account data, as soon as the email address get verified, a new user will be created in mongodb. With this solution an expire date could be set to remove not verified accounts after a certain amount of time)
Is it better to store a temporary user account in Redis or in MongoDB?

I would recommend storing the temporary user accounts in MongoDB. Storing them in MongoDB has three advantages over Redis:
If you store a temporary user in MongoDB, it will be very easy to convert them to a real user once they have verified. In fact, you could even have the temporary users and verified users share the same schema, with a has_verified field in that schema being the only difference between the two kinds of users. Changing has_verified to true is a lot easier than saving data from Redis to Mongo.
If you are not already planning to create a Redis database for your project, you will only have to maintain MongoDB. Maintaining MongoDB requires less effort and fewer computation resources than maintaining both Redis and MongoDB.
If you ever make changes to your user schema in the future, it would be easier to only make those changes in once place, i.e. MongoDB, rather than to make those changes in two places.

Related

Using a MongoDB Atlas database; how does one set up user accounts, if a user account/password is required to access the DB? (Node, express, mongoose)

Alrighty, so I have a MongoDB Atlas database set up, containing several objects. My current API has several get, post, put and delete end points which are working correctly. However, I am in the process of setting up user accounts and I am a little confused.
My project is built with React on the front end and my server is built with Node, express and mongoose. My goal is that of your typical web application and is as follows:
Go to main web app URL
Home page is a login or "create an account" screen.
Once logged in (or an account is created and you sign into it) you will then have access to get, post, put and potentially delete (if an admin) objects in my DB.
I have built a very basic sign-in, sign-out and "register an account" server which is working however, I am confused as to how to properly go about integrating this with the rest of my API. I currently have the server connecting to my Atlas DB using what is provided in the "connect" menu in the Atlas dashboard (without the < >)
mongodb+srv://<username>:<password>#<cluster-name>.ntwp5.mongodb.net/<collection-name>
Obviously, the username and password (which I can set in my Atlas dashboard) needs to be passed into the "username" and "password" fields in-order to connect to it. I was planning to use the same cluster and have a separate collection for users and my data.
What's confusing me is that in-order to connect to the MongoDB server above and gain access to the two databases, I need to pass in some username/password. However, in order to create an account (ie, creating a new username and password), I would already be utilizing a username and password to connect to the server.
So say I have a group of people in the same company using this application. Would I essentially have a single administrative username/password used by everyone to connect to the server URL? From there, users would be able to access the "users" collection and create an account. Do I then setup my existing API routes (which point to my collection of data) to check that the "signed-in" user exists before returning a successful request and access to that collection?
Or perhaps, the proper way is to use two completely separate databases; one for users and one for my data?
Sorry, I am new to working with Databases and I think the above makes sense to me but I want to verify if that is the correct way to go about handling this. Thanks!

Node Express Backend. How to manage mongodb connections? Mongodb users or collection of users?

I am developing a frontend with ANGULAR and backend with Node and Express. Is a simple backend for internal use in my company with a small quantity of users: 15-20. The backend connects to Mongodb. The mongo server is started with authentication and I can create users with built-in roles in mongo: read, write, etc.
But all the examples I found in tutorials usually creates a collection of users instead of using the mongodb built-in users.
As far I know, if use built-in mongo users I need to start a new connection for each user because the user and password is part of the Connection String URI
I have some doubts:
Is it a bad idea to use built-in users?
If I use built-in users. How to manage the logout of the user? I don't find examples.
"Users" in this context is usually connections to the database.
Lets say you have a database with data serving several applications. One which only has access to read the data, and another to write and update. You can make sure the read only app, wont write with 2 users of the database. Typically, you'll also have an admin user that has global all access for administrators.
When your coworkers wish to update some data through the second application. The application will authenticate to the database and write on their behalf. Whether or not someone has access to use the application to update data is not something the database should decide.
I hope this helps to understand the context of "user"

How to only show documents to specific users in a shared database?

I'm managing a multiuser app using Ionic 3.x, PouchDB, CouchDB and a node.js server running Superlogin. The app is steadily growing and I want to introduce a new feature.
My app has normal users and superusers. Each normal and superuser in my application gets it's own user database. There is also a shared database, let's call it the generaldb.
And here's my problem: Both users can create documents. These documents are synced to the userdb as well as to the general db. These documents have, amongst other things, a keyword (e.g. "colour": "green"). Superusers have access to a specific key. (In the above example that would mean that there are for example 5 superusers who can access the key green.)
Now, no normal user should be able to read, update or write other user's documents on the generaldb. Superusers should be able to read, update or write documents in the generaldb depending on which key they have access to. But they should not be allowed to change documents that don't match their key.
How can I restrict access for normal users in the generaldb, so that only documents created by themselves are synced to their devices and so that they couldn't change other users documents?
How can I ensure, superusers can change normal users documents, as long as they have access to the correct key?
How can I ensure superusers cannot change their own key, so that when number 2 is accomplished, they cannot manually work around the system?
One of the ideas of mine is to only let the users access their own db and have the shared db only accessible by superusers and then do a filtered replication of the userdb to the shared db. But this only solves 1 and seems very inefficient.

What is the standard way to represent "business-logic users" in CouchDB?

I'm new to couchDB and still reading tutorials. My question is if it is the normal way to represent every user of my application as a new database user, as it seems to be explained that way everywhere I look?
Let's say I have an online game with many different players - would I create a new "database user" for every player who registers? Or would I make my own database "players" and create a sign-in logic in the app? Not being used to document-driven DB's it seems strange to me not to distinguish between db-users and users of my application...
You could do it either way. First about couchdb users
Users in couchdb are stored in a special _users database
Database permissions are handled by a special _security document. This is specific to every database.
In security documents you add users that you have already stored in the _users database previously.
So you can certainly create a database per user. Before doing that ask yourself if the data that you store in each database is truly independent. Because you can't run map reduce queries across databases. So if you are planning to do aggregation across data for different users then this approach will not work.
Couchdb can also help you with app level authentication. Since couchdb uses a cookie based authentication:
Store your "business logic users" in the special _users database.
Authenticate it with the _session endpoint.
Extract the cookie header and sent it with your application headers.
All the logic for authentication is implemented for you by couchdb. All you have got to do is manipulate headers. Send the cookie from your application and when authenticating with couchdb send it with couchdb's headers.
If you prefer to write entire session management in your application that is fine too. In this case simply store the users in your database and verify that they exist before authenticating them. Like you would do with another database.
The benefit of using couchdb is that it is secure by default --using pbkdf2 encryption scheme to encrypt passwords.
If you instead want to manage all docs using a single database, but still implementing read/write ACLs, you can check the Chatty Couchapp Tutorial app from Smileupps App Store
It's a pure couchapp, relying on CouchDB only as its backend. The tutorial is still work in progress but the couchapp is fully working and you can download its source code.
It implements role/user based read/write ACLs using a single CouchDB database. This way you don't have to setup N replications where N depends on the number of your users. You only have one database containing all your data, easy to be queried on the fly(with temporary views) and for maintenance operations. Of course you can decide to increase the number of database, depending on type of your data and use cases.
A single couchapp contains all the necessary code for frontend, admin dashboard and server side API implementing business rules
The user, depending on his roles have different access to different sections. i.e. he can access the frontend website, but not the admin dashboard.
You can install the free trial, then download the source code with Smileupps deployment tools, change it, upload it back and check your changes.

How can I upload a picture in couch db and retrieve it

i am working on Couch DB ,i want to create a user profile after user signs up for my website.
During registration,the user uploads his image and then it is added to that user's document in Couch Db and retrieved so that all his details along with his image are displayed as his profile.
You can store a picture as an attachment, either in the user's profile, or, in preference, to a separate database. Here's uploading a single attachment to a new document:
curl -vXPUT $COUCH/testy/doc/attached-jpg --data-binary ~/tmp/swirl/docs/test/data/m74.jpg
Obviously if you're updating an existing document you'll need to provide _rev fields appropriately.
Typically the user profile is kept lean and the profile images are handled from a separate db which then doesn't require caching that in RAM on the server if not needed. A validation function can be used to ensure that the only user who updates a profile picture is the owning user.

Resources