JayK23
JayK23

Reputation: 253

Nuxt - is it possible to check if a user is logged in from SSR?

I created a Nuxt app that uses Django on the backend, i'm using the standard Django Session Authentication, so when i log in from Nuxt, a session cookie is set in my browser.

I've been trying for days to find a way to restrict some pages to authenticated users only, but i don't seem to find any working approach to do that. I need to check if the user is logged in before the page is loaded, so i tried to use a middleware but middleware won't work at all because the middleware is executed from server side (not client side) so there won't be any cookie in the request.

At this point, is there any other way to do this from SSR? Here is my request:

export default async function (context) {
  axios.defaults.withCredentials = true;
  return axios({
    method: 'get',
    url: 'http://127.0.0.1:8000/checkAuth',
    withCredentials: true,
  }).then(function (response) {
    //Check if user is authenticated - response is always False
  }).catch(function (error) {
    //Handle error
  });
}

Upvotes: 1

Views: 3907

Answers (2)

Levy_from_Odessa
Levy_from_Odessa

Reputation: 76

actually you can get cookies in a middleware.... Ill put my example, but the answer above is more correct .

middleware/auth.js

import * as cookiesUtils from '~/utils/cookies'

export default function ({ route, req, redirect }) {
  const isClient = process.client
  const isServer = process.server

  const getItem = (item) => {
    // On server
    if (isServer) {
      const cookies = cookiesUtils.getcookiesInServer(req)
      return cookies[item] || false
    }

    // On client
    if (isClient) {
      return cookiesUtils.getcookiesInClient(item)
    }
  }

  const token = getItem('token')
  const { timeAuthorized } = cookiesUtils.authorizeProps(token)


  const setRedirect = (routeName, query) => {
    return redirect({
      name: routeName,
      query: query
        ? {
            redirect: route.fullPath
          }
        : null
    })
  }


  // strange bug.. nuxt cant redirect '/' to '/login'
  if (route.path === '/') {
    setRedirect('users')
  }

  if (!route.path.match(/\/login\/*/g) && !timeAuthorized) {
    setRedirect('login', true)
  }

  
}

utils/cookies.js

import Cookie from 'js-cookie'
import jwtDecoded from 'jwt-decode'

/*
  TOKEN
*/
// Get server cookie
export const getcookiesInServer = (req) => {
  const serviceCookie = {}
  if (req && req.headers.cookie) {
    req.headers.cookie.split(';').forEach((val) => {
      const parts = val.split('=')
      serviceCookie[parts[0].trim()] = (parts[1] || '').trim()
    })
  }

  return serviceCookie
}

// Get the client cookie
export const getcookiesInClient = (key) => {
  return Cookie.get(key) || false
}

export const setcookiesToken = (token) => {
  Cookie.set('token', token)
}
export const removecookiesToken = () => {
  Cookie.remove('token')
}

export const authorizeProps = (token) => {
  const decodeToken = token && jwtDecoded(token)

  const timeAuthorized = (decodeToken.exp > Date.now() / 1000) || false

  return {
    timeAuthorized
  }
}

Upvotes: 2

Florian Pallas
Florian Pallas

Reputation: 582

If you are running Nuxt in SSR mode as server, you can access the cookie headers to find out if the user has a certain cookie. Packages like cookieparser (NPM) can easily do that for you.

But as you already found out, you can't do that in a middleware. What you could use instead is the nuxtServerInit action in your store (Docs). This action is run on the server and before any middleware gets executed. In there you can use cookieparser to get the user's cookies, authenticate them and save the any information you need in the store.

Later you can access the store in your middleware and for example redirect the user.

Upvotes: 2

Related Questions