Anh Khoa Ngô NodeJS is a JS VM with a stdlib. Nothing more, nothing less. You program everything on it and it certainly is not limited to web-applications (see for example Electron).
Sessions have nothing to do with PHP. They are a way to store state in between calls to the webserver. On the internet, you can never expect a client and server to have a constant connection. HTTP itself is not made for that and will terminate the connection after the request was successful. How would you handle a user clicking a link to their member-page if you do not store anywhere that they are logged-in? Even online computer games use sessions! Sessions are current, state-of-the-are and will probably stay with us for a very long time across all technologies. Btw, jwt is also just a session, with the exception that you can opt-out to store state on the server, so that you can send it to other services in the context of SSO (which, at the same time, means that you have to retrieve all information on every call, which is performance-wise slower). So, there is no "going back to that road", you are always on it, even when if it changes shape.
Is there any kind of storage I can store any kind of token for appending it later on in the http api call header.
Cookies, if you want them to be sent by the browser on every request. Other than that localStorage, WebSQL or just memory if you want to use it for AJAX, WebRTC or WS calls (though cookies can be queried by JS, too).
Marco Alka
Software Engineer, Technical Consultant & Mentor
This is one of many problems with today's frameworks and stacks. They pile up tech, but leave the most important parts to the people who use them - most of the time, the people use them because they lack experience and won't be able to integrate those most important parts - most likely, they don't even know that they have to implement them. Well, that's just me talking, so let's get to your problem.
One easy way to secure the web presence against DDoS is to use a proxy in front of it. You might use NGINX in order to do so and have it handle https, then forward the http connection to your NodeJS instance on a different port. Here's an article on how to configure NGINX so that it limits the number of requests. Don't forget that putting anything in front of your NodeJS application means that you no longer have the possibility to use advanced HTTP/2 techniques.
As for "unintended call"s, I don't really understand what you mean by that. Each and every call to an important procedure (for example "delete user") should have a call to an authentication routine, which makes sure the current user has the necessary rights. You might implement user-right-management by defining users with the right, use access levels, use ACLs, or give out access keys for certain operations. Just... make sure your authentication system is very stable and secure.
// Define users const usersWithDeleteRights = [ 'eve', 'alice', ]; function deleteUser(requestState, userToDelete) { if (usersWithDeleteRights.includes(requestState.session.userId)) { database.users.deleteById(userToDelete); return; } throw new Error('Insufficient rights!'); }// Use access levels const accessLevels = { none: 0, createUser: 1, updateUser: 2, deleteUser: 3, }; function deleteUser(requestState, userToDelete) { if (requestState.session.accessLevel >= accessLevel.deleteLevel) { database.users.deleteById(userToDelete); return; } throw new Error('Insufficient rights!'); }// Use ACLs const acl = { alice: { createUser: true, updateUser: true, deleteUser: true, }, oscar: { createUser: true, updateUser: true, deleteUser: false, }, }; function deleteUser(requestState, userToDelete) { if (acl[requestState.session.userId].deleteUser) { database.users.deleteById(userToDelete); return; } throw new Error('Insufficient rights!'); }// Use Keys const keys = { K_CREATE_USER: 1, K_UPDATE_USER: 2, K_DELETE_USER: 3, }; const keyRing = { eve: [K_CREATE_USER, K_UPDATE_USER, K_DELETE_USER], oscar: [K_CREATE_USER, K_UPDATE_USER], }; function deleteUser(requestState, userToDelete) { if (keyRing[requestState.session.userId].includes(K_DELETE_USER)) { database.users.deleteById(userToDelete); return; } throw new Error('Insufficient rights!'); }Of course, above code snippets are just explanatory. Please use a database to store information, like the keys and who has which keys. Also, use proper type checks (for example with instanced objects of a named function and for type-checking using
instanceof) and clean error propagation. I highly recommend using Monads, like Results, instead of throwing like a madman.Oh, and don't forget that each and every method of the ones listed above have their advantages and disadvantages. You should take a bit of time and read up on them, then decide for the one which is most suitable for your project. Personally, I recommend using ACLs, though I have very good experience with keys, as they are very generic and extensible (however also a bit harder to implement and take up more resources to check, because they are so generic - tbh, they are a pain when you want to have groups, which usually makes a lot of sense when you have more than three keys and five users :D).