1

Let's imagine a client opens your nuxt.js website on the index page. From there, they authenticate (you used @nuxtjs/auth-next for that purpose). Then they move to a secure page that only authenticated users can see. This secure page is a .vue file in your "pages" folder with middleware: ["auth"].

Now, how is this page really secure ? I mean, couldn't a malicious user temper with the page and access it without being authenticated anyway ? Because the "security" in this scenario is only implemented on the client side right ? [Edit]

Kay
  • 75
  • 8
  • `one way to display secure data on a page is to access it using asyncData from a secure backend API` where do you get this one from? Not sure to understand how is this more secure even with `target: 'server'` since this hook will be client sided once the hydration is done. – kissu Nov 12 '21 at 15:57
  • The asyncData hook is also client sided yes but if you use it to fetch the data on your server using an API you can check if the client is valid before sending the data. – Kay Nov 12 '21 at 17:48
  • If you want to protect only a specific subset of pages, make a [conditional in your middleware](https://stackoverflow.com/a/68985365/8816585). If it's a secure page (one which contains sensitive data and need a valid JWT from the backend), then the middleware will need to reach the backend for a validation. If it's a publicly accessible page, you don't even need to bother the backend. The backend of Nuxt (server-side) don't need to handle anything specific really since it will be client-side navigation anyway. At least, I don't see what a server-side middleware could achieve here. – kissu Nov 19 '21 at 14:43
  • Since we're not building a generated version of all the secure pages for 10k people here. As Facebook, we gonna fetch the actual data when the guy is connected, hence client-side only. Of course, public pages could be generated ahead of time. Also, when I was talking about backend below, I was referring to an external backend here, like Rails, PHP or Node.js. Of course, you could use your Nuxt app as a proxy, but the JWT should not be handled in the same repo but on something totally different. TDLR: `forget Nuxt backend, think regular non-nuxt backend` here. – kissu Nov 19 '21 at 14:46
  • Don't think about Nuxt as a really standard backend. I mean, with Nuxt Nitro (Nuxt3), you can have pretty advanced behavior mixing both client side and server side logic. But since you're struggling to understand how JWT, I do recommend taking it easy and splitting things in 2 parts to not mess-up and have a clear understanding on how this is working. Think about Nuxt as a way to improve performance and QoL in your case. Then, you'll be maybe able to setup a more advanced setup later on (if needed). PS: `@kissu` in your question edit is not sending me a notification btw. I am following it tho. – kissu Nov 19 '21 at 14:51
  • 1
    Sorry @kissu for deleting my EDIT, but I thought it would be more appropriate to create a new question as this was different from the question I created here in the first place. – Kay Nov 19 '21 at 15:25
  • No issues. It's better indeed. – kissu Nov 19 '21 at 15:25
  • @kissu, I don't understand why everyone say "you have to add a middleware on the routes you want to protect". I don't understand because middleware is run once on server-side (on the first request to the Nuxt app) and **then client-side** when navigating to further routes. So how could I write a middleware that has access to the header JWT token in the **Nuxt backend** when the middleware itself is run on the **client side**. It makes no sense ? – Kay Nov 20 '21 at 11:06
  • [As I told you](https://stackoverflow.com/questions/69945426/how-is-nuxt-auth-really-secure?noredirect=1#comment123805792_69945426), the "backend" here is not Nuxt but a regular backend like Node, Rails, PHP or alike. Don't think about Nuxt as a real backend but more as a more powerful frontend. Also, try to understand when people talk about middleware if it's for Nuxt or for the backend thanks to the "routes" keyword (backend specific). – kissu Nov 20 '21 at 16:31

2 Answers2

3

Your application being an SPA at the end, if you want to bypass a middleware with it's security checkup, you could disable the JS on the page. But then, since no content is generated directly, you won't see anything because it's not here (as a static file).

If your app is isomorphic (basically has a ssr: true), the auth module will still disable the access to those pages (you can double check).

At the end, the critical info is received when:

  • you do have a valid JWT token (after some login)
  • you submit an HTTP query to the backend
  • the backend acknowledges it and the token is valid
  • the backend gives you the sensitive info via an HTTP response

At the end, your client side code doesn't need to be secure. If somebody somehow hacks your client side state and reaches the sensitive page, he will still not have a valid JWT token since the verification still happens on the backend.
The one that can be generated only when sending the proper credentials to the backend and having the backend validating those.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • I know that you can perform any kind of checks you want on the client first page load / reload with using `serverMiddleware`. But when a client has the app already loaded on another page, with a valid JWT token, and they request for a secure page, can you check the JWT validity on the server before sending the page .js file to the client ? To my knowledge you can't, and this check is made client side. But am I missing something there ? – Kay Nov 12 '21 at 18:27
  • @Kay actually, a JWT's purpose is exactly to provide a check on the client side with some backend (our use case here). And all of your calls should be wrapped with it. If it's invalid or missing, you should logout the user (the module does it for you if I remember properly). The backend will throw you an error from the first call that do come with an invalid JWT. – kissu Nov 12 '21 at 20:01
  • And how practically can you do those checks on the server ? – Kay Nov 13 '21 at 13:32
  • @Kay when the frontend will reach the backend with it's token on a route, the backend will check the validity of the JWT with some database and give you a true/false. – kissu Nov 13 '21 at 14:36
  • Okay, I understand what to do, but where do you implement this in Nuxt ? – Kay Nov 13 '21 at 14:51
  • @kay you'll need an endpoint on the backend and to set the URL in your Nuxt app. This is the related page of the documentation: https://auth.nuxtjs.org/schemes/local The videos on the homepage of the module or some Google search may probably give you more info. Otherwise, a quick search here or in the Github issues (even maybe Reddit?) could be places to find a how-to guide. – kissu Nov 13 '21 at 15:40
  • Thanks but the url explains how to implement the login itself in Nuxt/auth but not how to check the validity of a connected user before to send them the requested page chunks. I don’t need to know what method to use, but where exactly in Nuxt to insert it if I wanted to do this by myself without any module. – Kay Nov 14 '21 at 17:21
  • @kay not sure to understand. The module handles the biggest part for you, set the variables and then use `loggedIn`S state to check if you're properly authenticated. If you want to do it yourself, I guess you can do it pretty anywhere you would like. A generic middleware or maybe an axios interceptor, it's up to your app and the way you want to implement it. If you want to implement it yourself without the auth module, Google on how it works and make your own implementation. – kissu Nov 14 '21 at 18:00
  • Sorry, I know I can be confusing sometimes. Let's imagine this scenario : - Your client first loads your site on the index page (/index); - They login and get a valid JWT token with nuxt/auth; - They navigate to a secure page that only authenticated users should be able to see; In this last step, the client gets the secure page chunks (a .js file) from the server by requesting it with a valid JWT token. Now my question is : Is there some kind of validation happening before providing the secure page chunks on the server ? – Kay Nov 17 '21 at 10:15
  • And if YES, let's say I had to implement this validation myself (without the auth module), where should I place it ? I mean where or in which option exactly in Nuxt ? Don't say `middleware` please because these are run client side or server side but only on first page load. So to me, anything client side is not safe and can be tampered with by an experienced user. – Kay Nov 17 '21 at 10:17
  • @Kay answer to the first comment: if somebody goes to a protected page, the actual protected sensitive stuff should actually be on the server. So accessing a protected page is not really a concern because there will be no data on it (if the JWT token is invalid). Also, the client will make an HTTP request. So, the response will not be a `.js` file but some JSON response from the backend. So no, there is not additional validation, there is only your backend checking your JWT which is fine by itself, because of it's asymmetric nature like SSH (the server keeps the important part in a database). – kissu Nov 18 '21 at 00:47
  • @Kay second comment: so yeah, this needs to happen on `middleware` because it will be a check that you need to do. Mainly, the only thing that your frontend needs to handle is: 1. if no token, ask for credentials 2. when the JWT will expire, the backend will send you a 401 status code, ask for a refresh token or redirect and ask again for credentials in Nuxt 3. pass it alongside all of your axios sensitive calls. Again, it's totally safe on client side, because your part of the token is **public** and the **private** key is hidden on the server. Some documentation: https://jwt.io/introduction – kissu Nov 18 '21 at 00:54
  • Thanks for the response and the documentation link. I read everything I could on JWT tokens. What I still don't understand though is how to make **the backend** aware that it has to check the JWT in the header before providing the JSON of the secure page to the client. – Kay Nov 18 '21 at 11:33
  • I've been looking for an answer for days now but I still can't seem to put my finger on it. It's making me crazy. – Kay Nov 18 '21 at 11:35
  • @Kay not a backend expert on this one, but I'd say that you need to have a middleware on some specific endpoints of the router. If somebody hits a protected route, he needs to provide a JWT (coming from Nuxt), you then double-check that the token is a valid one with a function on your backend (+ database), then if it's valid, you can call the related controller to go get the data and send it back to Nuxt. You can have a lot of approaches here, but there is 100% a backend package to handle all the refresh, generation, validation, revokation etc... TLDR: it's a thing to be done on both stacks. – kissu Nov 18 '21 at 11:42
  • 1
    Ok thanks a lot @kissu for your time. For those interested in the last question, maybe I will get a precise answer [here](https://stackoverflow.com/questions/70037012/in-nuxt-js-how-do-you-restrict-some-routes-only-to-clients-with-a-valid-jwt-toke). – Kay Nov 19 '21 at 15:13
0

Now, how is this page really secure ?

The protected content is served from a request if a valid access token has been provided by the client. The protected content is provided at runtime.

Because the "security" in this scenario is only implemented on the client side right ?

The security is not only implemented on the client side. The premise is: The access token has been obtained securely through an authentication flow with an auth-server. I recommend to read more about auth flows if this sounds unclear. Auth0 has some good documentation on different flows. https://auth0.com/docs/authorization/flows

Then, what is the best way to show a complex page to authenticated users only ?

The content is provided at run-time. Server-side or client-side. There are some setup guides here for Nuxt. Here is the first (Auth0) I found from the list. https://auth.nuxtjs.org/providers/auth0

I don't know how updated those guides are, but the auth service providers tend to have updated guides themselves.

Kunukn
  • 2,136
  • 16
  • 16
  • As I commented in the other response : let me try to rephrase my question. Let's imagine this scenario : - Your client first loads your site on the index page (/index); - They login and get a valid JWT token with nuxt/auth; - They navigate to a secure page that only authenticated users should be able to see. In this last step, the client gets the secure page chunks (a .js file) from the server by requesting it with a valid JWT token. Now my question is : **Is there some kind of validation happening before providing the secure page chunks on the server ?** – Kay Nov 17 '21 at 10:23
  • And if YES, let's say I had to implement this validation myself (without the auth module), where should I place it ? I mean where or in which option exactly in Nuxt ? Don't say middleware please because these are run client side or server side but only on first page load. So to me, anything client side is not safe and can be tampered with by an experienced user. – Kay Nov 17 '21 at 10:23
  • @Kay is basically the go-to for "how to handle secure calls between a backend and a frontend SPA" so yeah, don't worry it's not hacky and insecure in any way. Otherwise, it wouldn't be one of the most used authentication method as of today SPA's usage. The only thing, is maybe that you'll need to wait for the token to expire if you want to remove the access to somebody. But this is not a big issue, if you fix the `access_token` to 5min or so. And if your token is revoked, the backend can also invalidate it on your next client side navigation too. Read some documentation for the main concepts. – kissu Nov 18 '21 at 00:59
  • "Is there some kind of validation happening before providing the secure page chunks on the server" This sounds like a static compiled JS file? then I would say no without being 100% sure. Protected content happens at runtime. If an anonymous user navigates to a secure page, then we throw the user to the login page or something. If the user is authenticated. Then the protected content is requested at runtime. – Kunukn Nov 18 '21 at 12:03
  • I don't see Nuxt preventing access to "privileged" route source files at all. I'm able to download js chunks from a Nuxt server without being authenticated, given I know (or guess) the hash filename. – Charlie Schliesser Feb 15 '22 at 23:38