Node.js user authentication and unprotected routes - javascript

I couldn't come up with a better name for the question so I apologize for that.
In my application you can make an account, create files and send the link of a file you created in a "view-version" to whoever you want.
The routes to create, delete, read,... files are protected, however, the "view-version" is not.
The way I handle it right now is the following:
The link to the view-version consists of the id of the file and a token the user receives upon log in.
When whoever receives the link opens the page, the token and id (that's the id of the entry created in MongoDB) are authenticated and if they are valid the user sees the page.
Obviously, the token times out after some time and I'm assuming that, once the token times out, the viewer will no longer be able to view the page (I didn't actually test this but it just makes sense I guess).
I'm new to creating websites that require user authentication for certain sites so I'm rather clueless about how to solve this.
If I let the viewer access the file just using the id, that'd be insecure since he could view ALL files by trying different id's (a viewer is not supposed to be able to view all files).
So, I guess what I'm trying to do is to publish the view-version of a certain file to a selected audience.
I was thinking about creating a permanent token that I could use instead of the token created when logging in/out so the viewer would always be able to view the files but I'm not sure how big of a security risk that is.
I tried googling how to best go about that, however, my search was unsuccessful.
How is such a concept usually implemented?

Related

Reactjs Authentication: make route available if you have the link

In my application the user is able to create files and to publish them. You need to be logged in in order to create/read/update/delete a file but there's a link with which you can simply view the file (no option to edit etc. and you don't need an account to view it).
Up until now, you needed a token for authentication to create/edit/etc the files in your account, however, if you had the link to the "view-version" of the file, you did not need a link in order to retrieve the file data and to view the file (meaning the route for fetching the data in the view-version was not protected).
However, this seems like a big security risk to me, as you can access the file data (albeit not the user data).
What I came up with is the following:
Besides the file-id, which I use to identify the file in question, I could also enter the token into the querystring, so whoever views the file could be authenticated.
I'm very new to this so I don't know much about what is a security risk. Sending the token in the querystring also seems like a security risk to me but I don't know how else to do what I'm trying to achieve and googling did not get me very far.
To sum it up, my questions are:
1. Is sending the token in the querystring secure?
2. If not, how can I achieve what I'm trying to do?

Can I do some sort of authentication when dynamically loading modules via webpack?

The prevailing pattern in single page app security seems to be:
User authenticates themselves
User gets a token
User makes api requests with the token
That's fine for limiting access to data, but in a lot of cases, code for UI that might have to do with another user seems to be present and can be accessed by changing some values via something like redux. That UI gives away information through certain menu options, request structure (ajax functions tied to things like buttons and forms), instructions, etc. In general, it seems like a good idea to hide that information if you can.
One solution is to split the app into user specific bundles and put each bundle behind an authenticated endpoint. The only problem I have with this solution is that you end up needing to reload a bunch of shared modules on login.
I'd prefer to dynamically load the modules by doing something like this (with webpack):
require.ensure(["./file1"], function() {
// do things
});
I haven't dove into dynamically loading chunks too much so I'm not sure what endpoint is hit to load ./file1 or whether that's something you set up yourself, but theoretically I don't see any reason why you couldn't pass a token along and authenticate the user requesting ./file1. Does anyone know how you would do that? Is it an idea worth pursuing, or is there some reason why I shouldn't want to do something like this?

One click ebook

I am implementing a referral program and giving people and ebook as a reward. Is there a way without using a database to make it so that the ebook is only available for 24 days to the user? I don't want users to share the ebook PDF. What can I put in place to prevent this? I'm guessing I should also update robots.txt?
I'm using node js and JavaScript
Save file as usernameOfUser_deadlineTimestamp.pdf. Now when a user requests a file, simply fetch filenames from the folder and look for file starting with name usernameOfUser. Now, get the current timestamp and compare it with the deadlineTimestamp you get from the filename. If current timestamp is less that deadlineTimestamp, serve the file else show error message. Use fs to determine filenames etc.
The proper solution is to implement some kind of authentication to know who (which user) is requesting the ebook and then some kind of authorization to decide if you will serve him the ebook or not (not if the 24 day period is expired).
These information must be available on your server in any form, and regardless of the form it is a database already.
Now the robots.txt is useless in this situation as no crawler can authenticate as a valid user, so no one can have access to the resource.
The database-less solution is to generate a pretty long link for every user and encrypt the all the needed pieces of information in that link.
So would a link like http://example.com/gvdcwt5f23ydvuztb2ftyuzfydy826ngnuy2u2gfzgnyg2y6gn2gyf6g2f2uynfu contain the user name (or any other identification) and the expiration date. So every time this link is requested the server decrypts it and serves the requested ebook.
robots.txt is still useless as you won't have the ebook available as http://example.com/ebook.pdf and there will be no mention of those long links, no robot will bother to scan your server by guessing working links.
Regarding the handling of the pdf when the user downloaded it, you have no more control over it. You can place copyright notice in the pdf itself to prevent sharing by gentle users, but there is no way of protecting the contents of the pdf file. You can encrypt it, but once user can share it with credentials, you can generate pdf for all users with invisible information stored in it have the ability to identify who shared it if you find a shared copy, but any of these and certainly many others is probably not worth the time spent by implementation of such a "protection".

How do I handle communication between multiple Node.js servers for each user?

I'm trying to make a user log in just once, and have his information on all the servers. Any changes made to the user's information will instantly be available for all servers. Is this possible to do without having each user "log in" separately for each server?
Sort of like the $_SESSION for php, but for Node.js
Design 1 -
What I think would be best to do, but don't know how to share socket data between servers, perhaps using something like PHP's $_SESSION?
Design 2 -
What I'm currently doing:
User uses socket.emit to main.js
main.js adds user information onto the emit
main.js emits to the appropriate server
Appropriate server emits back to main.js
main.js finally emits back to user
This seems awfully inefficient and feels wrong
If your information is primarily static, you can try something similar to JWT. These are cryptographically signed tokens that your authenticating server can provide and the user can carry around. This token may contain information about the user that you want each server to have available without having the user accessing it.
If it's not, you may be looking into sharing a database across all servers, and have that be the point of synchronization between them.
Updates based on our comments (so they can be removed later):
If you decide to use auto-contained JWT tokens, you don't need to be making trips to the database at all. These tokens will contain all the information required, but it will be transparent to the end user that won't have insight into their contents.
Also, once you understand the JWT standard, you don't necessarily have to work with JSON objects, since it is just the serialization approach that you can switch by another one.
You'd provide one of these tokens to your user on authentication (or whenever required), and then you'd require that user to provide that token to the other servers when requesting information or behavior from them. The token will become your synchronization approach.

Possible "autoprint" feature requested for a web application

I was asked an odd question this morning--We have customers who have a number of PDF reports hosted on our services which are accessed through https (not a direct file link, but accessed by a rest url).
Customers often print these reports on a daily basis.
The request is that these reports automatically print (could be default printer) each morning.
My initial reaction is to laugh, because obviously this is impossible without some user action. But the more I think about this, the more I am inclined to believe there may be ways. For example, if there is some generic "print" user with limited access, and if the browser is left open, and some Javascript on the login screen checks the time of day, it might be possible to retrieve files at a specified time and print. I don't believe I can automatically print--but at least I can open a print dialog.
I know the request to automatically send things to a far away printer from our web services is impossible. Wondering if I can provide the next best thing, and if anyone has a good idea to share here.

Categories