javascript - Node.js, Vue.js and Passport.js. .isAuthenticated() always returns false? Axios headers possibly? - Stack Overflow

I'm moving a project over to Vue.js and I can't get any of my middleware to check if users ar

I'm moving a project over to Vue.js and I can't get any of my middleware to check if users are logged in or to check user ownership of things to work. After searching endlessly, I believe that the problem is that the headers I send from my client to server don't contain the passport serialized user or something? How can I make this work?

Here is my login route on the back-end:

      router.post("/login", function (req, res, next) {
    if (!req.body.username || !req.body.password) {
      res.send("Error");
    } else if(req.body.username.length > 40 || req.body.password.length > 40){
      res.send("Error");
    } else if (req.body.username) {
      req.body.username = req.body.username.toLowerCase();
      next();
    }
  }, passport.authenticate('local', {
    failureRedirect: '/login'
  }), function(req, res){
        User.findById(req.user.id, function(err, user){
          if(err){
            res.send("User not found");
          } else {
            res.send(user.toJSON());
          }
        })
  });

Here is my login page on the client side:

          async login () {
          const response = await AuthenticationService.login({
                username: this.username,
                password: this.password,
            })
            if(response.data == "Error"){
                this.$router.push({
                    name: 'login'
                })
            } else {
            this.$store.dispatch('setUser', response.data._id);
            this.$router.push({
                name: 'home'
            })
            }
        }

Here is the axios call that AuthenticationService.login is referencing:

    login(credentials){
    return Api().post('login', credentials);
},

Api es from:

import axios from 'axios';

 export default function(){
   return axios.create({
      baseURL: `http://localhost:8081/`
   });
  }

So how do I make the front-end send the right headers to the back-end after a user is authenticated? As you can see, I store the user id in a vuex state, but I don't think that would be safe to use to confirm ownership and whether or not users are logged in, right? Or would it? I could easily just send that over in the requests, is that right? I feel like that's not safe enough, but Idk what I'm talking about.

EDIT: Here is the passport setup in app.js

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.use(flash());
app.use(cookieParser());

app.use(express.session({ //5a6ba876578447262893ac69
    secret: "sessionSecret",
    resave: false,
    saveUninitialized: false
  }));
app.locals.moment = require('moment');
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

I'm moving a project over to Vue.js and I can't get any of my middleware to check if users are logged in or to check user ownership of things to work. After searching endlessly, I believe that the problem is that the headers I send from my client to server don't contain the passport serialized user or something? How can I make this work?

Here is my login route on the back-end:

      router.post("/login", function (req, res, next) {
    if (!req.body.username || !req.body.password) {
      res.send("Error");
    } else if(req.body.username.length > 40 || req.body.password.length > 40){
      res.send("Error");
    } else if (req.body.username) {
      req.body.username = req.body.username.toLowerCase();
      next();
    }
  }, passport.authenticate('local', {
    failureRedirect: '/login'
  }), function(req, res){
        User.findById(req.user.id, function(err, user){
          if(err){
            res.send("User not found");
          } else {
            res.send(user.toJSON());
          }
        })
  });

Here is my login page on the client side:

          async login () {
          const response = await AuthenticationService.login({
                username: this.username,
                password: this.password,
            })
            if(response.data == "Error"){
                this.$router.push({
                    name: 'login'
                })
            } else {
            this.$store.dispatch('setUser', response.data._id);
            this.$router.push({
                name: 'home'
            })
            }
        }

Here is the axios call that AuthenticationService.login is referencing:

    login(credentials){
    return Api().post('login', credentials);
},

Api es from:

import axios from 'axios';

 export default function(){
   return axios.create({
      baseURL: `http://localhost:8081/`
   });
  }

So how do I make the front-end send the right headers to the back-end after a user is authenticated? As you can see, I store the user id in a vuex state, but I don't think that would be safe to use to confirm ownership and whether or not users are logged in, right? Or would it? I could easily just send that over in the requests, is that right? I feel like that's not safe enough, but Idk what I'm talking about.

EDIT: Here is the passport setup in app.js

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());
app.use(flash());
app.use(cookieParser());

app.use(express.session({ //5a6ba876578447262893ac69
    secret: "sessionSecret",
    resave: false,
    saveUninitialized: false
  }));
app.locals.moment = require('moment');
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Share Improve this question edited Jul 28, 2018 at 0:15 Setheroni asked Jul 28, 2018 at 0:06 SetheroniSetheroni 1452 silver badges12 bronze badges 11
  • For sessions to work in passport/express, you need to define [de]serializeUser on the passport instance . Can you show all of the express/passport middleware you are using? – Dan Commented Jul 28, 2018 at 0:10
  • As for storing the user id in vuex state, that's totally fine as long as you use that for UI purposes (and not authoritative). You should store the users session token in cookies which are HttpOnly and use those to authenticate/authorize the user on the server side. – Dan Commented Jul 28, 2018 at 0:11
  • Thanks for the edit. What happens on the server side when you attempt to access POST /login? – Dan Commented Jul 28, 2018 at 0:16
  • Thank you, Dan. I included the passport and express middleware in an edit above, however I think my issue is solely based on your second ment. How to I get the token? How do I save it? And how do I use it in other requests? – Setheroni Commented Jul 28, 2018 at 0:16
  • When I attempt to access POST/login t works exactly as it should – Setheroni Commented Jul 28, 2018 at 0:17
 |  Show 6 more ments

2 Answers 2

Reset to default 8

Your issue is because your frontend and backend are on different domains.

Cookies, which passport.session()/express.session() use to maintain a user session, are scoped to a specific domain.

When you call axios.get() on the protected resource, axios will not send or receive cookies because localhost:8080 is a different domain to localhost:8081.

Try axios.get('/path/to/your/resource', { withCredentials: true }) and axios.post('/login', { username, password }, { withCredentials: true })

This would have been present even without Vue so long as you're using AJAX to make these calls.

requests.js

let axiosConfig = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': 'http://localhost:3000/',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
  }
}

server.js

var express  = require('express');
var app      = express();
var cors = require('cors');
app.use(cors({credentials: true, origin: 'http://localhost:8080'}))

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1740951744a4280745.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信