Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Session ID Cookie in Nuxt Auth

Tags:

django

nuxt.js

I have the following set up in my nuxt.config.js file:

auth: {
redirect: {
  login: '/accounts/login',
  logout: '/',
  callback: '/accounts/login',
  home: '/'
},
strategies: {
  local: {
    endpoints: {
      login: { url: 'http://localhost:8000/api/login2/', method: 'post' },
      user: {url: 'http://localhost:8000/api/user/', method: 'get', propertyName: 'user' },
      tokenRequired: false,
      tokenType: false
    }
  }
},
localStorage: false,
cookie: true
},

I am using django sessions for my authentication backend, which means that upon a successful login, i will have received a session-id in my response cookie. When i authenticate with nuxt however, i see the cookie in the response, but the cookie is not saved to be used in further requests. Any idea what else i need to be doing?

like image 925
Dominooch Avatar asked Mar 30 '20 21:03

Dominooch


2 Answers

This is how I handled this, which came from a forum post that I cannot find since. First get rid of nuxt/auth and roll your own with vuex store. You will want two middleware, one to apply to pages you want auth on, and another for the opposite.

This assumes you have a profile route and a login route that returns a user json on successful login.

I'm also writing the user to a cookie called authUser, but that was just for debugging and can be removed if you don't need it.

store/index

import state from "./state";
import * as actions from "./actions";
import * as mutations from "./mutations";
import * as getters from "./getters";

export default {
  state,
  getters,
  mutations,
  actions,
  modules: {},
};

store/state

export default () => ({
  user: null,
  isAuthenticated: false,
});

store/actions

export async function nuxtServerInit({ commit }, { _req, res }) {
  await this.$axios
    .$get("/api/users/profile")
    .then((response) => {
      commit("setUser", response);
      commit("setAuthenticated", true);
    })
    .catch((error) => {
      commit("setErrors", [error]); // not covered in this demo
      commit("setUser", null);
      commit("setAuthenticated", false);
      res.setHeader("Set-Cookie", [
        `session=false; expires=Thu, 01 Jan 1970 00:00:00 GMT`,
        `authUser=false; expires=Thu, 01 Jan 1970 00:00:00 GMT`,
      ]);
    });
}

store/mutations

export const setUser = (state, payload) => (state.user = payload);
export const setAuthenticated = (state, payload) =>
  (state.isAuthenticated = payload);

store/getters

export const getUser = (state) => state.user;
export const isAuthenticated = (state) => state.isAuthenticated;

middleware/redirectIfNoUser

export default function ({ app, redirect, _route, _req }) {
  if (!app.store.state.user || !app.store.state.isAuthenticated) {
    return redirect("/auth/login");
  }
}

middleware/redirectIfUser

export default function ({ app, redirect, _req }) {
  if (app.store.state.user) {
    if (app.store.state.user.roles.includes("customer")) {
      return redirect({
        name: "panel",
        params: { username: app.store.state.user.username },
      });
    } else if (app.store.state.user.roles.includes("admin")) {
      return redirect("/admin/dashboard");
    } else {
      return redirect({
        name: "panel",
      });
    }
  } else {
    return redirect("/");
  }
}

pages/login- login method

async userLogin() {
  if (this.form.username !== "" && this.form.password !== "") {
    await this.$axios
      .post("/api/auth/login", this.form)
      .then((response) => {
        this.$store.commit("setUser", response.data);
        this.$store.commit("setAuthenticated", true);
        this.$cookies.set("authUser", JSON.stringify(response.data), {
          maxAge: 60 * 60 * 24 * 7,
        });
        if (this.$route.query.redirect) {
          this.$router.push(this.$route.query.redirect);
        }
        this.$router.push("/panel");
      })
      .catch((e) => {
        this.$toast
          .error("Error logging in", { icon: "error" })
          .goAway(800);
like image 71
timelf123 Avatar answered Oct 24 '22 02:10

timelf123


The cookie is sent by the server but the client won't read it, until you set the property withCredentials in your client request (about withCredentials read here)

To fix your problem you have to extend your auth config with withCredentials property.

    endpoints: {
      login: { 
        url: 'http://localhost:8000/api/login2/', 
        method: 'post'
        withCredentials: true 
      }
    }

Also don't forget to set CORS policies on your server as well to support cookie exchange

Example from ExpressJS

app.use(cors({ credentials: true, origin: "http://localhost:8000" }))

More information about this issue on auth-module github

like image 1
Andrew_Sparrow Avatar answered Oct 24 '22 02:10

Andrew_Sparrow