1
votes

Not sure if the title summarises my question well.

Basically, I am trying to authenticate routes such as checking if user exists etc. I only want to allow requests coming from my frontend application to be approved, but, since no user is signed in there is no token to send.

Api request -

mywebiste/checkUser/email

This route is unprotected on my backend because no user is logged in. BUT I want to protect this route, in such a way that it's accessible only from the frontend.

Some ideas I came up with were adding specific headers tag from the frontend and check them on the backend, but that could be easily replicated, is there something more secure like using tokens etc.

I am using React and Node.js

3

3 Answers

0
votes

Same origin policy is going to give you some basic protection, but basically if an API endpoint is exposed publicly, it's exposed publicly. If you don't want that route to be publicly accessible you need to add access control.

If you use that route to check if a user is already registered, you could, for example, merge it with the user registration route and send a different error code if the user already exists (which is not a great idea because it leaks which emails are registered on your system).

0
votes

You can verify that a request was originated by a user (by authenticating him) but you cannot verify that a request comes from a particular client because of these two reasons :

  • If you include some API key in your client (web page or other), it's easily retrievable by everyone (the best thing you could do is offuscate it which makes things slightly harder but still possible)
  • If you send an API key over the network it's easily retrievable as well

The only thing you could do is prevent other web pages from calling your backend on behalf of the user, by using CORS (which is actually active by default if you dont specify an Access-Control-Allow-Origin header)

0
votes

I ended up creating a kind of working solution, so basically, I create a new base64 string on my frontend and attach that to the header while making a request to the backend. The base64 string is different every minute, so even if the header is copied, it differs every minute and is combined with your secret key.

I have made a package so that people can use it if they want - https://github.com/dhiraj1site/ncrypter

You can use it like so

var ncrypter = require('ncrypter');

//use encode on your frontend with number of seconds and secret key
var encodedString = ncrypter.encrypt(2, 'mysecret1')

//use decode on your backend with same seconds and secret
var decodedString = ncrypter.decrypt(encodedString, 2, 'mysecret1');

console.log('permission granted -->', decodedString);