2

In Nuxt.js this is one way to implement authentication :

  1. The client authenticates by sending an HTTP request with its credentials in the body to an API route of the Nuxt backend ;
  2. The Nuxt backend responds with a JWT token that allows the client to access protected routes ;
  3. Finally, when the authenticated user tries to access such a route, they make an HTTP request to the Nuxt backend with their JWT token inserted in the header ;
  4. The backend validates the JWT token and responds with the requested page JSON data to the client.

What I don't understand is how to make the Nuxt backend aware that for some protected routes it has to check the JWT token of the client before providing the page JSON data. I mean, where exactly in Nuxt can I implement this kind of validation ?

Kay
  • 75
  • 8
  • Hi, wasn't my [comment here](https://stackoverflow.com/questions/69945426/how-is-nuxt-auth-really-secure#comment123805564_69945426) precise enough? – kissu Nov 19 '21 at 15:14
  • do you want to protect an page or do you just need an API response? – bill.gates Nov 19 '21 at 15:16
  • Also, let's say that if you go to a route that needs to have some secure content served, you'll need to send a valid JWT to the backend. If you don't send it, the backend will error anyway and you won't receive any result at all. A simple approach for this would be to check if the end user is reaching a secure page, if he doesn't have a valid token, redirect him to the login page. If he does, let him send his query with the appropriate token to your **regular** backend (not Nuxt). – kissu Nov 19 '21 at 15:18
  • @Ifaruki at the end, those 2 are pretty similar no? If a page is protected and you don't have what is needed, you won't get a response. And, if you don't get a response, the page will be blank, with no data really, so it's "protected" because there is no sensitive content leaking. – kissu Nov 19 '21 at 15:20
  • @kissu well for pages i use `middlewares` but for backend APIs i use express middlewares witch are actually different – bill.gates Nov 19 '21 at 15:20
  • Here, it's a [tag:nuxt] question so mainly focused on Nuxt. Besides, at the end: the logic is the same on both front and backend. You go to some specific place, there is a check-in, if you fill the conditions, you can pass. `router's middleware + pages` vs `routes middleware + controller` is basically the same thing. @Ifaruki – kissu Nov 19 '21 at 15:23

1 Answers1

2

Well i am confused a bit first you say API data the other sentece you say JSON page.. however. If you want to protect an PAGE then you create an middleware

middleware/auth.js

export default async function ({ store, $axios, redirect }) {
  let valid = await $axios.$post('/api/checktoken')
  if (!valid) {
    redirect('/')
  }
}

You need to create an API where you check the token. Usually you need to put the token in your header like Authentication: Bearer token... however i simply save my token inside an cookie. Because if you send an HTTP request to the server the cookies gets automatically sended with it so i dont need to do some extra work.

Next step is you go to some page and set your middleware auth.

page.vue

<script>
export default {
   middleware: "auth"
}
</script>

However if you want to protect some backend routes you can do it like this. Create again an middleware

  async authenticate(req, res, next) {
    let token = await cookieService.getTokenFromCookie(req)
    if (!token) return errorService.resError(res, 400, 'Authorization failed')
    let tokenValid = await tokenService.verifyToken(token)
    if (!tokenValid)
      return errorService.resError(res, 400, 'Authorization failed')
    let decodedData = tokenService.decode(token)
    if (!decodedData)
      return errorService.resError(res, 400, 'Authorization failed')
    res.locals.userId = decodedData.userId
    res.locals.role = decodedData.role
    next()
  }

In this case you basically need to read the token out of your cookie. (in case you dont use cookies you will need to read it out of your header so for this you should create an function that reads your token out of the header)

Check if token is even there.

Verify if token is valid.

Decode the token so you can access the data in it

Now you can also put the data to your res.locals. The advantage is that this data is scoped to this current request and you can access it in the next middleware / endpoint.

then you call next() to step to the next middleware / endpoint

function endpoint(req, res) {
   let { userId, role } = res.locals
   do something....
}

So the route looks something like this:

app.use("/some/api/point", authenticate, endpoint)

The good thing about is you can put authenticate in every API route you want to protect.

bill.gates
  • 14,145
  • 3
  • 19
  • 47
  • Are you sur your answer is **Nuxt.js related** ? Because Nuxt.js middlewares are mostly run **client side** (at least after the first request to the Nuxt app and navigating to further routes) so you don't have access to `req` where the header containing the JWT token is... – Kay Nov 20 '21 at 11:21
  • @Kay `some backend` != `nuxt`. Also, your question cannot be solved with a Nuxt2 only tag because you'll need a secure backend at some point (other than Nuxt so). So yeah, your question is broader and the shown solution is related to Node mainly. – kissu Nov 20 '21 at 16:35
  • I am sorry but my question is only 100% Nuxt.js related. So when I say `backend` I am talking about the server Nuxt itself creates when you build the app (as you said in Nuxt 3 this is nitro for example). I am not talking about any other exterior backend. For example when you use the module `nuxt/auth`, everything is happening in Nuxt own backend and frontend. So my question is legit and the answer shouldn't reference any exterior backend at all. – Kay Nov 22 '21 at 14:12