T O P

Is it possible to check if a user is authenticated before accessing page?

Is it possible to check if a user is authenticated before accessing page?

sheetsofstyle

Here is a quick example using middleware as a router guard using vuex. If you have an authenticated user set in vuex, you can check that, then throw the error() handler inside the middleware if they are not authenticated. /middleware/auth.js export default function ({ store, error }) { const user = store.getters['authorizeduser'] if (!user) { error({ title: 'Unauthorized', message: 'Please login to view this page', statusCode: 401 }) } }


LeifErikson12

Thanks! Yes that works but the problem is that the middleware will always return 'not authenticated' because i can't send cookies from server side middlewares


de1pher

I think the others have already answered your question for you, I just wanted to add that you might want to look into [nuxt-auth](https://auth.nuxtjs.org/) which handles authentication on frontend and it sets up all the necessary middleware to do what you need.


LeifErikson12

Thank you! I've looked into it but it's not what I need since I'm using Session Authentication. The problem I'm having is not that I don't know how to do this, the problem is that when the Middleware executes from server side, no cookies are sent in the request so the user will always be unauthenticated according to the backend


DiLocoNacho

Multiple methods are possible. If you use created() instead of beforeMount(), it should work just fine. Tip: I made an layout with an auth check on the created hook. For every page that should be protected by authentication, I use that layout.


LeifErikson12

Thank you a lot for your answer! I tried created() too and i have the same problem i had with beforeMount(): the page will load before executing the redirect, so basically for a bunch of seconds the user will see the restricted page before being redirected, which isn't the best solution. Can you expand a little on the other solution you mentioned?


Redwallian

Try using `asyncData()` within the page component - it seems like you're trying to run an API call anyways, and this function is perfect for data fetching agnostic-wise; redirect if no auth data is returned.


LeifErikson12

Thank you a lot! I think i tried that too but i had the same problem as the other methods like created() and beforeMount(): the page will be rendered by the browser and then the redirect is executed, which means that the user will see the restricted page for a bunch of second before being redirected, which is a bit ugly. I'm trying to solve that


Redwallian

Well, as you can see in the [lifecycle hooks](https://nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle/) available, the user shouldn't be able to see it because it's still compiling on the server during `asyncData()` before sending back to client. I use Nuxt for work, I've run into the same problem before, and I know this method works, so I suggest giving it a go again and see what you come up with.


LeifErikson12

Thank you a lot for your help! Already i just tried to create a new page with some basic code: The response to the request will be `False`, but if i send the same request after the page is loaded, the response will be `True`, which means that the cookie is not sent with the headers when the request is sent from asyncData. Does asyncData execute from server side? Thanks again, sorry but i'm fairly new to Nuxt Edit: yes, indeed it will run from the server, which means that the request won't have the cookie


Redwallian

`asyncData()` executes from server-side - you might need a package to handle cookie setting/getting/unsetting, such as nookies. You can import into your component and then grab cookies for your header before the API call.


LeifErikson12

Thanks a lot. So you are saying i should set the cookie in the Axios request's headers and then send the request to the backend? Yes, i tried that too by setting the cookie in `headers: {}`, but for some reason the backend still didn't receive the cookie


Redwallian

I dunno, it depends on what you want to send to the backend - you can think of cookies as browser-storage-based javascript objects. Are you trying to send the whole object? Are you trying to send only certain key/value pairs? This is kinda out of the scope of the original question; I would recommend asking this via another post.


LeifErikson12

I think I didn't explain myself quite well, or I wasn't specific enough, so let me explain: my backend uses Session Authentication, so in order to check if a user is authenticated, the backend will check the session cookie in the request. The nuxt Middleware is executed from the server side, which means that no cookie is sent, so even if the user is authenticated in Nuxt, according to my backend the user is always not authenticated, because from server side no cookies are sent to the backend. The only solution would be to execute the Middleware from client side but this is not possible because of a Nuxt design choice. TL;Dr the question I asked is: is it even possible to check if a user is authenticated in Nuxt since Middlewares are executed from server side, which means that no cookies are sent to the backend, which means that backend can't check if that user is authenticated?


Redwallian

> is it even possible to check if a user is authenticated in Nuxt since Middlewares are executed from server side, which means that no cookies are sent to the backend, which means that backend can't check if that user is authenticated? I'm having a hard time following this logic. Django should be able to set a cookie in the response back to the client. Maybe you or I am missing a few steps, so let me know if I'm missing anything - 1. When someone logs in using a payload (email/password, token, whatever), they should be receiving a cookie (request is an API call with a payload, response is a cookie and a message saying "Ok!"). 2. Your app redirects to some place like "/profile". 3. Your Profile component has a middleware set. Since this is a programmatic redirect, Nuxt is using `process.client`, so you have to use a JS cookie package to obtain credentials from this cookie to authenticate by inserting it in your axios config and sending out the API call in the `asyncData()` hook. 4. Your user hits the refresh button on his/her browser. This turns into a server-side process called `process.server` on the endpoint "/profile" - reloading the browser tab should reset everything, so this possibly puts the user in an "unauthenticated state" - with the exception that your browser still having the cookie set. Then, all go through the rendering process again by calling the middleware (which [can and should](https://github.com/nuxt/nuxt.js/issues/2507) access this cookie) and setting the axios headers correctly. Run through `asyncData()` again, check that auth is set, then the user can see his/her profile page again. I would recommend [this post](https://briancaffey.github.io/2021/01/01/session-authentication-with-django-django-rest-framework-and-nuxt/) - it uses Nuxt SSR/Django DRF and shows you the entire process of authentication in a clean perspective involving vuex and `nuxtServerInit()`. Also, someone [created a package](https://github.com/microcipcip/cookie-universal/tree/master/packages/cookie-universal-nuxt) to read both client and server cookies you should look into.


LeifErikson12

Let me try to explain, sorry but i'm not english so let me know if what i say is weird. So when you login in Django, Django will set a sessionID cookie in the browser. Then, every time a user sends a request, the session cookie is in the request, so Django will get the request, get the cookie and it can say if that user is authenticated or not and who is that user thanks to the cookie. Now suppose i login from nuxt: 1. I login succesfully from Nuxt and Django sets a cookie in the browser. 2. Now suppose from a standard page you sent a POST or GET request (using a button or whatever action) from Nuxt to Django using Axios: the client sends the request to the Django backend, since in the headers there will be that user's cookies, Django will say that the request comes from X authenticated user. 3. Now suppose you refresh the page and a middleware needs to check if the auser is authenticated. So the page is refreshed, the middleware executes from server side and sends a request to Django. Since the middleware executes from server side and not client side, there are no cookies set, so Django will think that the request comes from an anonymous user, so Nuxt will redirect me. I hope that's more clear, but the problem is very simple: in Session Authentication, Django sets a cookie in the user's browser. Since in SSR mode Nuxt middlewares are executed from server side, when the middleware is fired there will be no cookie in the request, since it executes from server side and not client side. EDIT: I just realized we are saying the same thing. When the middleware executes from client side, everything works without any problem. When the middleware executes from server side (after a refresh for example) the user is unauthenticated even when in reality the user did authenticate. Yes, i can access the Cookie from the server side middleware, but i'm having an hard time setting it in the request. I tried everything but Django always receives an empty string in the Cookies field. I set it in the axios request like that: return axios({ method: 'post', url: 'http://127.0.0.1:8000/testreq', withCredentials: true, headers: {'sessionID': ''}