Vue or Axios don't store session cookie
Solution 1
In my experience this tends to be an issue arising from CORS ( Cross-Origin Resource Sharing ).
Namely if your API_URL is not on the same domain as your application's auth.js is running Axios will not be able to send cookies by default. You can read more about how to allow Cross Domain credential use to your API here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Access-Control-Allow-Credentials
Practically speaking you can use the CORS module https://www.npmjs.com/package/cors to apply the necessary headers in some configuration akin to the following on the server side:
var express = require('express')
, cors = require('cors')
, app = express()
app.use(cors({
origin: "myapp.io",
credentials: true
}))
It is particularly important that you specify the origin url that your auth.js script is running from otherwise an attacker could use a Cross Site Scripting Attack.
Hopefully that helps!
Solution 2
You could also globally set axios credentials:
axios.defaults.withCredentials = true
From within the docs:
// `withCredentials` indicates whether or not cross-site Access-Control requests // should be made using credentials withCredentials: false, // default
arckosfr
Updated on June 04, 2022Comments
-
arckosfr almost 2 years
I face a problem but i don't know where it be and why. I have a backend API based on express4(nodejs) We have implemented Auth with passport.
When i use postman, i log with post on /login. it store a session cookie and all route is now accesible since the cookie is not expired.
But with my frontend based on VueJS. I use Axios for doing the Request. The request seems to be good. but any cookie is stored so the browser do a loopback on he login page.
I have tried without the auth check or not it the same. But on postman it work.
the main.js for Vue:
import Vue from 'vue' import VueRouter from 'vue-router' import Axios from 'axios' Vue.use(VueRouter) import auth from './utils/auth' import App from './components/App.vue' import Login from './components/Login.vue' import Home from './components/Containers.vue' require('font-awesome-loader'); function requireAuth (to, from, next) { if (!auth.checkAuth()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } const router = new VueRouter({ mode: 'history', routes: [ { path: '/', name: 'containers', component: Home, beforeEnter: requireAuth }, { path: '/login', component: Login }, { path: '/logout', beforeEnter (to, from, next) { auth.logout() next('/') }} ] }) new Vue({ el: '#app', router, render: h => h(App) })
And the auth.js (where the request is done)
import axios from 'axios' import { API_URL } from '../config/app' export default { user: { authenticated: false }, login (email, pass, cb) { LoginRequest(email, pass, (res) => { this.user.authenticated = res.authenticated if (this.user.authenticated) { console.log('ok') if (cb) cb(true) } else { console.log('pasok') if (cb) cb(false) } }) }, checkAuth () { if (getAuth()) { this.authenticated = true } else { this.authenticated = false } }, logout (cb) { this.user.authenticated = false if (cb) cb() } } function LoginRequest (email, pass, cb) { axios.post(API_URL + '/api/login', { email: email, password: pass }).then(response => { if (response.status === 200) { cb({ authenticated: true }) } else { cb({ authenticated: false }) } }, response => { cb({ authenticated: false }) }) } function getAuth (cb) { axios.get(API_URL + '/me').then(response => { return true }, response => { return false }) }
EDIT : my cors use on the backend :
// allow CORS: app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT$ res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,$ next(); });
Thank !