Protected areas and rest APIs

If I’ve a front end (vanilla JS) querying my own rest API, am I right in thinking that if I want to implement a protected area of the site, say an admin panel, the best I can do is have authorisation on the API and hide the link to the admin URL on the front end?

I can’t actually prevent someone navigating to the URL itself can I?

Thanks!

Nick

Hi,

I think you’ll need to add details. I’ve done the api certificate and I’m working on authentication and authorisation in ‘Advanced Node and Express’ section of the quality assurance part of the curriculum. (you’ll have to look up a lot of stuff to get it but the code is there). I’ve learned about libraries that you can use. You can make a backend with node js (express library for node) and then use passport.js for authentication. There are other methods available, many other methods. So what exactly do you mean with ‘authorisation on the API’ ?
If I’ve completely misunderstood you, well, explain please :slight_smile:
Greets,
Karin

Hi Karin

Thanks for the reply!

So yes, passport js or any authentication authorises access to the data on the backend, but if the html isn’t rendered server side that doesn’t stop me navigating to www.example.com/admin-page. AFAIK it just prevents that admin page from displaying the data that I’m not authorised to see.

Does that make more sense?

Thanks again,

Nick

Hi,

I’d love to help but I’m still quite the beginner here. I’ve just got my API and Microservices certificate and I’m just beginning to learn about his. Do you mean a path to an endpoint defined in your backend? I certainly wouldn’t use an anchor tag, just doesn’t feel right, but you can make an endpoint and send stuff to your backend.
Or do you want the user to see and use that admin panel in a way that he can only see his own data? If so, I would create a view that only shows what he needs to see and deal with all that on the backend. Parameters, database, all that.
Have I understood you ?
Greets,
Karin

Hello there,

There are many ways to handle this kind of situation.

  1. Implement a route with authorisation:
app.route('/admin').post(authorisationMiddleware, routeHandler)
  • in authorisationMiddleware you confirm the user has the permissions, and continue to routeHandler with access
  • If user does not have permission, redirect the user to the login/home/error page
  1. Do not have specific pages with special permissions (I tend to go with this route, because it is easier, but does require a specific kind of site layout)

In the case of 1, the use can try to navigate to /admin, but they will always be redirected, without the permissions.

Hope this helps

No worries Karin, it’s hard to describe this in a post so it’s probably my fault! :grin: It sounds like you’re talking more about rendering the html on the server - which if I was sensible I would be doing :joy: Unfortunately I am not!

@Sky020

1: So it wouldn’t have to rely on the backend (that’s doing the authorisation) to be serving the html as well? It just authenticates and if it fails tells the browser to redirect using res.redirect('/') or something? So it doesn’t really stop someone getting to the page if they really wanted to (which wouldn’t be a problem if there was no data)

2: Yeah, there’s a definite need for a page that only an admin can see, unfortunately. I don’t really need to hide the structure of the page itself, but I’m just trying to check I have the right mental model for this - that someone (who isn’t the admin) will be able to navigate to that page, see the html (if solution #1 isn’t implemented), but not see the data because the backend fails to authenticate

Really I should just do server side rendering, but I wanted to get a rest based site done for the portfolio :man_shrugging:

Thanks for all the help!

1 Like

Well, it can stop someone from getting to the page, because you could only send the HTML (e.g. admin-panel.html), if authorised.

This is kind of where I think I might be getting confused - if the front and back ends are separate then surely it isn’t possible to have the server that authenticates you do this because it isn’t responsible for serving the html?

Maybe I’m approaching the whole thing incorrectly - I don’t have any particular need to separate the two, I was just trying to create a rest API that was distinct from the front end

Remember, the server serves everything. The only reason there is an html page to view is because the client requested the page from the server. So, you (the server) have complete control over what is served, and what is not.

Now, there are some silly cases where that is not the case. As someone not willing to invest in a custom domain, but still wanting fullstack apps associated with my GitHub account, I have my client-side served by GitHub Pages, and my backend hosted on Heroku. So, my backend acts as a pure REST API with nothing but “data management”.

This is not a recommended way to serve a webpage, though. So, other than for the sake of being free I would avoid this.


Remember, we are not actually talking about SSR, here.

Ah ok. You’ve actually answered another question I’d been scratching my head over for a few days now too, thanks!

So I do have a custom domain and I’d been trying to implement what is usually seen in tutorials / and with React - that harsh split between a front and backend because they’re doing something similar to you with a pure rest API.

It just started to feel a bit silly, given the same domain, the same server, and nginx proxying to a different express server for the front and back end, for no real reason that I could see.


So if I have a route like /admin and that now returns an html document, is the choice now between having that page make another request to the server for data, or use a template engine?

Thanks a lot btw, this has been really helpful, saved me a lot of headache!

I see no reason why you cannot just include multiple parts in the response. That is, send the file with some JSON.

I am glad this is helping some. I am still wrapping my head around the different/best ways to implement different architectures, and mostly find myself making a Frankenstein’s monster of what methods I have seen.

I’ve no idea how that would work in practice though? How would you reference that json response in your JS? Normally it would be the result of an asyc call or similar, this would be… :man_shrugging:

After digging into it, with Express this would be undefined behaviour. So, if you really want to, your best options are as you said:

  • Template engine
  • Multiple requests from client

Yeah… god, I’ve not even thought about how using templates is going to mess with my webpack config.

I hope it doesn’t.

I know it will.

:laughing:

Apache can be configured to restrict access by IP address. This may not be the solution you are looking for, but something like you are asking can be done.

That’s useful to know, especially the use of headers, thanks.

To be honest I was more just generally interested in whether this was an accepted/known downside to a rest API + vanilla frontend, because at least in this case I don’t think I care if anyone can access the html of the admin page, as long as the response from the server requires authorisation.

I just thought I might have missed something on the frontend, along the lines of Reacts protected routes or similar :slightly_smiling_face:

I think this applies only after you have done some sort of authentication. You were asking about preventing people from getting to the authentication form in the first place. You’d have to do that via the web server.

Ah, no, sorry, I was asking about preventing people from accessing an admin html page.

  • frontend server serves admin.html, which would then make a separate request to /admin route of backend server
  • backend server has an /admin route requiring authentication

so in the above there’s nothing stopping someone navigating to /admin.html and seeing the admin page, but not the admin data, if that makes sense?

Maybe that would need authentication on the frontend server too? It just feels like I’m missing something :man_shrugging: