Session between REST calls with node.js for mobile - node.js

I have to do registration for a mobile app with node.js (express.js) backend. The registration process involves sevaral steps:
1. provide email
2. verify email
3. provide personal details
4. upload photo
For each of these steps there should be a separate call to the server API ( possibly through REST ).
How to keep the session so that the server knows that the consecutive calls come from the same client ? This is a mobile app so cookie based session won't work I think. Could you guide me somehow ? Is using a JWT token the right way to go ?

I'm not an expert but...
So here you need to firstly answear a question:
How much time does user have to create such account? For example, if you won't store information that user had started to create account and server restarted ( for whatever reason. eg error ), you will lose this info. So it would be worth to store this in some db.
You can use redis, mongodb, some sql db or just system files (not recommended ) it's up to you.
Assuming you want to persist such info, you can create REST endpoints.
So for example, you can have entry in MongoDB (which basically stores JSON structures).
NewAccount { id: <unique_id> , email, info, images }
So each endpoint you create will set info in this MongoDB entry.
Example:
1) POST /user/create -> this would create entry in MongodDB
2) PUT /user/create { body: { field: 'email', value: 'p#pp.pl' }}
3) POST /user/create/finish
We have one more question -> how to identify user? You can try to identify it by IP address. If it's mobile app, you have different ways to store info (eg user token) eg:
https://developer.android.com/guide/topics/data/data-storage

As per your step given :
sevaral steps: 1. provide email 2. verify email 3. provide personal details 4. upload photo
1.Register by email and password
Suggestion: You need to ask for email and password.
i) When a user enters the email and password check user exists with email if not then send a verified email and redirect to login.
2. Once User verified. Now user tries to log in.
i) When a user tries to login check email and password is correct or not.
ii) If correct then generate JWT Token on the backend and send back to APP.
ii) Now using JWT Token you can manage the user session on the app.

Related

how to create a survey app only allow the invited person visit only in a secure way

I have one Node.js app and database is MSSQL. I have implement the basic functionality like register, login and others like adding users. The authentication of the api is using JWT, so when a user login, he will receive a token saved on the cookie, just like normal app.
I'm going to add a new survey functionality to the app. With the survey, it does not require user login and does not ask to create a new user account, but only the person receive the invitation link can visit. What I current save on the survey main table is the email address and person name going to receive the survey and one auto generated UUID. The survey link may be /survey/UUID.
How should I do it and how to secure the survey form?
What I was thinking is to create a new token for each survey use only and attchecd with the invitation link, and then validate that token. But because it does not ask the login, I cannot validate the token with email. Should I need a Recaptcha only? Or I need to the login here, or at least need to the user confirm his email address so the token can be verify?
You could use id (primary key) AUTO increment on the main table, and 10-15 char as password. you generate token based on your format such as url/id+password. Id is always unique so its guarantee that each user will have their own token.

What is the most secure way to invite an unregistered user to my app?

I'm working on a React app with an Express backend, with Passport for authentication via JWTs. A registered user needs to be able to send an invitation to someone else who is unregistered, to come use the application. The unregistered user should not be required to register in order to see a subset of our content. THIS IS IMPORTANT - the unregistered user needs to be able to have access to some data that belongs to the registered user and would otherwise be unviewable without being authenticated. I built an invitation model to track these invites, who sent them, who they're being sent to, etc.
What is the best/most secure way to identify this user?
My current guess is to create a unique string and store that in the invitation object and pass that to the unregistered user via email. So they will have a link to our app with ?invite_id=SOME_ID_HERE appended at the end. When they reach our app we will verify that the string matches an invite in our DB.
Is this the best approach? Should I be doing something more secure, maybe a pair of public and private keys? Any advice would be greatly appreciated, thanks!
I think it's best to keep this as a random ID in your database. That way, the users can be removed later. And, if you do associate this new user with that random ID later, you can use an existing profile that you're already storing rather than having them start from scratch.
In other words, create a new ID for this user but set it up so that they can only access things via this URL until they create an account.

build a One Time Password authentication server

Problem
In our system we have:
Two apps: a backoffice in reactjs and an app for user in react-native
An API (with postgres db)
Hubspot (user informations, phone number, etc.)
We want to add an authentication server to secure our user data and allow user to connect to the mobile app. That server would provide tokens and a link between Hubspot (that carries user informations) and the user in the API db. The db would store only hubspot user id and the api user id and some timestamp. We want to use a One Time Password using text messages.
The workflow would be something like:
the user want to connect to the app (for the first time or not). The app is requesting a phone number.
the phone number is sent to the auth server that checks if it exists in hubspot. If the user phone number exists but nothing yet in the database, that means we need to create a new user (in the auth server database AND in the api). If the user number exists and already in the database there is nothing to do. In both case, a token is generated and the user is able to connect (still need to understand how to do that). If nothing exist in hubspot, the user wouldn’t be able to authenticate in the app.
Questions
Am I going in the right direction? Creating an authentication server, is it a good idea or completely useless? Should we implement our logic directly in the API? The system is about medical information and data should be protected.
Concerning the OTP, what should we send to the user if the phone number actually exists? The auth token or a random string to require the actual token?
the phone number is sent to the auth server that checks if it exists
in hubspot. If the user phone number exists but nothing yet in the
database, that means we need to create a new user (in the auth server
database AND in the api). If the user number exists and already in the
database there is nothing to do. In both case, a token is generated
and the user is able to connect (still need to understand how to do
that). If nothing exist in hubspot, the user wouldn’t be able to
authenticate in the app.
I do not think sending the phone number to the auth server is a good idea, instead you generate a code and save it on some backend server or some backend database and then text the user the same exact code. The reason for saving the code on the backend is to compare it to the one the user provides at some point in the future.
That is a unique identifying piece of information, not a phone number, peoples' phone numbers change all the time.
The user presumably receives the text message, that is the only reason we need the phone number for to send that text message and they can enter that code back into the application.
So the user sends us the correct code and that comes to the backend server. It's then compared on the server and if the user entered the correct code, send them some further identifying token, such as a JSON Web Token that identifies the user for future follow up requests.
This is what it means to be authenticated. Once the user successfully enters the token, we provide a user with a JSON Web Token to specifically identify them and say, hey this user did correctly enter a one time password, here is some identifying information on the user.

How can I implement exclusive/invite-only user registration?

I'm creating a site with user auth, and I plan to limit access using either invites or some other method.
The site is built on Node, Express, and MongoDB. I plan to use Passport JS, mainly because it's the only method I've learned (this is my first personal project).
The only idea I have is a "secret code" on the registration page. Thus only those I've told the code can register. I have a feeling there are more elegant or secure ways to handle this, and would love any recommendations!
I think your idea is correct in principle - it's the same method used for registration/beta keys for games. You generate a unique 'key' for each user you invite to register. They register with that key and it is marked 'used' in your database; this prevents other users from discovering that key and re-using it.
You could also use email addresses in essentially the same way. The email address that is used to register must be on your 'invite list'. And when you 'confirm' an address by sending a 'click this link to confirm' email you will have to generate another key for authenticity.
Therefore, upon registration with an invited email, you could generate a key as follows:
require('crypto').randomBytes(48, function(err, buffer) {
var key = buffer.toString('base64');
// then save the key with the new user in the database
});
Then send an email with a confirm link containing the key, for example:
https://www.mywebsite.com/users/confirm_email/{key}
This link would call a 'confirm_email' action on your server, look up the specified key, and enable the account it is associated with.
You might want to add an expiry along with each key creation for a bit added security. Maybe only 24 hours to confirm the email.
You don't need any secret codes if it's with invitations :
When someone invites someone else, you store the email invited somewhere. You simply need to check that a new user is "on your guest list" when he tries to register.
Of course, to be "secure" this approach assumes you actually checks that an email address properly belongs to the user that registers, for instance with a verification email, as done usually. The point is that you don't need an additional token.
One solution I can think of just generates the token using the senders token (use jsonwebtoken signed with expiry time and sender's token). Now when the user who is invited will receive the link, let say: http://localhost:5000/invite/${token} and the link is clicked then a GET request will be sent to the server so catch that request and then in that request in the backend decode that token and check your user database if that user exists i.e sender and token is not expired then it's valid invitation so now directly redirect the invitation receiver to the register page else send the message that invitation is not valid.
Hope this help.
Let me know your views.

How to integrate Google or Facebook login with my database?

I want to understand how to integrate auth of Google or Facebook with my database.
I have a login system with email and password, users table and messages table for that represent messages of users.
When someone registers, a new user with userID is created.
When a user login to the system with email and password he gets an auth token,
and for each action the user makes, like POST or GET requests for fetching or creating a new message, he sends the token he got and the system finds the userID by this token, and then finds his own messages.
Now I want to add Google and Facebook login, how should I do it now?
I can get from each of them a token. but the user isn't actually exists in my user table, so when I search the user by his token, I won't get anything, because he is not exists in the user table, and when I want to insert him to this table, I need to fill the password field there but I can't get it from google.
What should be the approach to do thing like this?
Thank you.
When they first login, you can request their email from Facebook or google, the user will give your application access to see their email address.
At this point you could create a new user with that email and add a flag to say they came from facebook/google.
The rest works as normal, they would get a token from your application and so on.
In case they come back and login again, you don't need to register them as they are already in your database.
In case you need extra info from them, (more then just the info you can request from facebook/google) you could redirect them to a special form, for their first login.

Resources