Can Vue or React SPA block access for some pages? - vue.js

I'm building a SPA(Single Page Application) with Vue.js now,
and there will be some admin pages which authorized person can access to it.
And the Vue frontend server will communicate with backend Express.js server with REST APIs.
In this case, I thought that SPA is the concept that loaded at once and react with it, not like traditional MPAs such as apache, which run the code on the server and toss it with HTML, so the admin pages will be in source code even though the informations are authorized by Express.js with ajax(axios), am I understand right?
So even though I use Vue-router beforeEach authorization, someone can see the frames of admin pages, right?
If so, is there any better idea to block access for them?

All the code of the SPA doesn't need to be loaded as one piece at once. You can use Async Components to split the code into multiple chunks loaded dynamically at runtime only when needed. This is especially useful in your case as the code for the Admin part doesn't need to be downloaded/parsed/executed by non-admin users (which is probably majority) - see Lazy Loading Routes
On top of that your Express server app should authorize every server call anyway. If unauthorized user somehow manage to execute and display the Admin part, it will be useless for him if the server doesn't return any "admin only" data to display or allow any admin only operations to be executed on server side...

Related

How is client-side authorization with VueRouter safe?

EDIT: In a single-page-app, ALL of the static content is loaded in the SPA, so if there is anything remotely sensitive in the static content, it can be viewed from within the browser. The only solution is to not use SPAs and render authorized pages from the server side, and if those pages require modelview AJAX JS controllers, don't exponse anything sensitive in the controller code, as that will be served static too.
I've studied the code for VueRouter and read several other examples that use guards and prechecks to perform authentication (either by a cookie or session data token) to block certain routes unless the user has permission.
I don't understand how this is safe? The VueRouter example blocks the dashboard page, but I can literally view the so-called "blocked" page in the browser debug console, and then edit the JavaScript in the source panel to bypass the authorization by deleting the check in the requireAuth function and replace with 'next()'.
I'm clearly missing something, but if the content and javascript can be viwed/edited in browser, how is this a valid method of authorizing parts of your website?
Securing your app should be done in backend since you have full control of that machine. VueRouter, as you clearly said, is typically used for showing/hiding UI elements depending on authentication and authorization. You always must assume that anyone could read and modify your frontend in their local machines.
To be clear, It doesn't matter whether you're using Vue, React or any other frontend framework, security must be applied in the backend.

How do dynamic API calls work in Nuxt.js static vs SSR mode?

Even after reading through multiple articles explaining the differences between static and SSR rendering I still don't understand how dynamic API calls work in these different modes.
I know that Nuxt has the fetch and asyncData hooks which are only called once during static generation, but what if I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?
I'm making a site that shows user generated content on most pages, so I have to make GET requests everytime one of those pages is visited to keep the content up to date. Can I do that with a static site or do I have to use SSR / something else? I don't want to use client side rendering (SPA mode) because it's slow and bad for SEO. So what is my best option?
There is actually no difference between either asyncData() or fetch() hooks when you do use target: static (SSG) or target: server (default, SSR).
At least, not in your use-case.
They are used mainly by your hydrated app.
As a reminder, when using either SSG or SSR, your static page will be hydrated and will become an SPA with all the dynamic functionality that we love. This combo of SSG + SPA or SSR + SPA is called an universal app (or isomorphic app).
Both asyncData() and fetch() will be called upon navigation within your client side SPA.
There are also some things happening on the server side, like fetch being called (by default) when you request the server for an SSR built app.
Or the fact that when you generate your app (if using SSG), you can reach some API and generate dynamic routes (useful in the case of a headless CMS + blog combo for example).
For performance reasons and to have a quick build time, you may pass a payload and use it in an asyncData hook in the dynamic route, as explained here
Still, a static Nuxt app, is basically just an app built ahead of time, with no need for a Node.js server, hence why an SSG app can be hosted on Netlify for free (CDN) but and SSR one needs to be hosted on something like Heroku (on a paid VPS).
The main questions to ask yourself here are:
do you need to have some content protected? Like some video courses, private user info etc...already in your Nuxt project (if SSG, disabling the JS will give access to the generated content)
is your first page a login? Is it mandatory to access the rest of the content? Like an admin dashboard (you cannot generate content ahead of time if the data is private, think of Facebook's feed being generated for every account, not feasible and not secure as above)
is my API updating super often and do I need to have some super quick build time (limitation on free tiers essentially)? (SSG will need a re-generation each time the API changes)
If none of those are relevant, you can totally go SSG.
If one of those is important to you, you may consider SSR.
I do recommend trying all of them:
SSR (ssr: true + target: server) with yarn build && yarn start
SSG (ssr: true + target: static) with yarn generate && yarn start
SPA only (ssr: false + either target: static, target: server also work but who wants to pay for an SPA?!) with yarn generate && yarn start
Try to host it on some platforms too, if you want to be sure to understand the differences beyond your local build.
You can use this kind of extension to also double-check the behavior of having JS enabled or not.
I will probably recommend to take the SSG path. Even tho, if your content is always changing you will probably not benefit much from SEO (eg: Twitter or Facebook).
This github answer could maybe help you understand things a bit better (it does have some videos from Atinux).
PS: I did a video about this on the latest Nuxtnation that you can find here.
I use dynamic HTTP requests inside component methods (e.g. when submitting a form via a POST request)? Does that even work in static sites?
The short answer to this question is that yes, it does work. In fact you can have http requests in any life cycle hooks or methods in your code, and they all work fine with static mode too.
Static site generation and ssr mode in Nuxt.js are tools to help you with SEO issues and I will explain the difference with an example.
Imagine you have a blog post page at a url like coolsite.com/blogs with some posts that are coming from a database.
SPA
In this mode, when a user visits the said URL server basically responds with a .js file, then in the client this .js file will be rendered. A Vue instance gets created and when the app reaches the code for the get posts request for example in the created hook, it makes an API call, gets the result and renders the posts to the DOM.
This is not cool for SEO since at the first app load there isn't any content and all search engine web crawlers are better at understanding content as html rather than js.
SSR
In this mode if you use the asyncData hook, when the user requests for the said URL, the server runs the code in the asyncData hook in which you should have your API call for the blog posts. It gets the result, renders it as an html page and sends that back to the user with the content already inside it (the Vue instance still gets created in the client). There is no need for any further request from client to server. Of course you still can have api calls in other methods or hooks.
The drawback here is that you need a certain way for deployment for this to work since the code must run on the server. For example you need node.js web hosting to run your app on the server.
STATIC
This mode is actually a compromise between the last two. It means you can have static web hosting but still make your app better for SEO.
The way it works is simple. You use asyncData again but here, when you are generating your app in your local machine it runs the code inside asyncData, gets the posts, and then renders the proper html for each of your app routes. So when you deploy and the user requests that URL, she/he will get a rendered page just like the one in SSR mode.
But the drawback here is that if you add a post to your database, you need to generate your app in your local machine, and update the required file(s) on your server with newly generated files in order for the user to get the latest content.
Apart from this, any other API call will work just fine since the code required for this is already shipped to the client.
Side note: I used asyncData in my example since this is the hook you should use in page level but fetch is also a Nuxt.js hook that works more or less the same for the component level.

In a Nuxt SSR application, what happens on server and what on client?

I'm on Nuxt 2.13 and building an e-commerce website.
But the are some issues with my server resources, my first load of site takes some time (on route change every thing is ok and fast, just the init is slow).
So i wanna know which parts of my site will be on server and which parts on client browser.
for example as recommended, i use fetch() with axios to get page/component data. as i read the docs it is said on render route it is server-side and on navigation it is client side. so what does that mean? my axios call in fetch() in on server or client? what about my other axios calls in methods to backend?
what i wanna understand is that which parts are on server? and can i make them client-side to save server resources? (I'm afraid with some users the resource usage get too high!!)
That's point of fetch. It's called when it's needed. On server side during initial page load, than all page state is send along with rendered page to client. All following navigation is calling fetch on client side only.
On basic level, you can't care about it.
In reality, to speed up initial load, you may decide to load something always on client. Then you can move it to mounter() hook which is always called only on client side.

Separate back-end and front-end apps on same domain?

We are building a fully RESTful back-end with the Play Framework. We are also building a separate web front-end with a different technology stack that will call the RESTful API.
How do we deploy both apps so they have the same domain name, with some URLs used for the backend API and some for the front-end views?
For example, visiting MyDomain.example means the front-end displays the home page, but sending a GET to MyDomain.example/product/24 means the back-end returns a JSON object with the product information. A further possibility is if a web browser views MyDomain.example/product/24, then the front-end displays an HTML page, and that webpage was built from a back-end call to the same URL.
Finally, do we need two dedicated servers for this? Or can the front-end and back-end be deployed on the same server (e.g. OpenShift, Heroku)
You are gonna to dig yourself... deep :)
Simplest and most clean approach with no any doubt is creating a single application serving data for both, BE and FE, where you differ response (JSON vs HTML) by the URL, pseudo routes:
GET /products/:id controllers.Frontend.productHtml(id)
GET /backend/products/:id controllers.Backend.productJson(id)
Benefits:
single deployment (let's say to Heroku)
name space managed from one app
No need to modify the models in many apps after change in one of them
else if
If you're really determined to create a two separate apps, use some HTTP server as a proxy - for an example nginx - so it will send all requests to domain.tld/* to application working at port 9000 (which will answer with HTML) but requests to domain.tld/backend/* redirect to application working at port 9001 responding with JSON.
else
If you are really gonna to response with JSON or HTML depending on the caller you can try to compare headers to check if request was sent from browser or from AJAX call in each controller , but believe me that will become a nightmare faster than you thing... insert the coin, choose the flavor
I thought of a different solution. I'm going to deploy back-end to a subdomain like
http://api.myapp.example/
and deploy front-end to the main domain:
http://myapp.example/
but I think you'd better use 2 different hosts, one for front-end and one for back-end (I searched the Google and this was the result of my investigations
Other possibility (therefore as separate answer) is using a possibility added in Play 2.1.x a Content negotiation I think it's closest for that what you wanted to get initially :)
Indeed its much easier to create a MEAN STACK APP and use one hosting like Heroku for instance.
Your frontend is what it is, front end for your backend. It will be easy to access backend / restfulAPI's and frontend like this:
http://localhost:3000/api/contacts (to access and consume your API endpoint)
http://localhost:3000/contacts (frontend)
NB: localhost:3000 or http://yourapp.example/api/contacts (api)
http://yourapp.example/contacts (frontend)
It's in the URL

Can an API and regular backend exist at the same time?

I've been looking at backends and APIs for a while now. It seems that sometimes devs will build a regular backend (in say a language like PHP) that handles all the backend matters and sometimes devs will instead choose to build out their backend through an API and then use their own (and possibly other) sites to pull data from this API.
I was wondering this:
Say I want to build a regular backend using a server-scripting language like PHP, which I will use to not only render my main website, but will also allow me to do other server-side scripting etc. Then say I want to use this data from the current site and make it accessible to another site of mine through API calls. Will it be possible to build an API on top of a regular backend?
If the answer yes, how complex can it get to achieve something like this?
What tools or design strategies (if any) would you have or have used for achieving this?
This is an old question, but since I'm here, I may as well provide an answer for anyone wondering. Joe is asking about server-side web APIs versus regular server-side code.
Yes, you can have a "regular" backend and an API backend exist at the same time. If your backend is in PHP, you can refactor and extend your code to handle API requests.
Like Patrick Evans said, an API is the backend. If your backend PHP code communicates with a database to manipulate or retrieve data, then you can consider this an API transaction. Whenever your backend receives a request, evaluates/actions that request, and returns a response, it is essentially acting like an API.
Let's say you own example.com, with an index.php file in the root directory - so when a user requests example.com in their browser, this index.php file is processed and served to them. Now, you can set up this index.php file to handle both regular page requests (i.e. the php script returns an html template that is rendered by the browser) and API calls. This can be as complex or as simple as you want it to be.
The best way to handle this would be to assign different routes for rendering your main webpages and API calls. You can set up routes in the following way...
example.com/index.php?route=api&data=users can be handled by your 'API code' in index.php to return a JSON response containing a list of all the users in your database, while example.com/index.php?route=home will just return your website's home page.