使用NodeJS,Express-Session和Passport进行身份验证失败

时间:2018-05-19 16:25:02

标签: javascript node.js express authentication passport.js

我已成功通过google OAuth API进行身份验证和登录。

const passport       = require('passport');
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
const passportInit  = require('./app/routes/auth')
const session = require('express-session');

module.exports = (app, db, passport) => {

    app.use(session({secret: "ahskfjdhkjshadkjfhlajsdhlfkj"}));

    passportInit(passport)

    app.use(passport.initialize());
    app.use(passport.session())

    app.get('/', (req, res) => {
        if (req.session.token) {
            res.cookie('token', req.session.token);
            res.json({
                status: 'session cookie set'
            });
            console.log(req.session.token);
            console.log(JSON.stringify(req.user))
        } else {
            res.cookie('token', '')
            res.json({
                status: 'session cookie not set'
            });
        }
    });

    app.get('/auth/google', passport.authenticate('google', {
        scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/youtube']
    }));

    app.get('/auth/google/callback',
        passport.authenticate('google', {
            failureRedirect: '/' // Fail: To err Page
        }),
        (req, res) => {
            req.session.token = req.user.token;
            userString = JSON.stringify(req.user);
            userObjectValue = JSON.parse(userString);

            userId = userObjectValue['profile'].id;
            userName = userObjectValue['profile'].name;
            userGivenName = userName.givenName;

            const details = {'userId': userId};

            db.collection('users').findOne(details, (err, item) => {

                if (item == null) {
                    res.redirect('http://localhost:80/Register.html');
                } else {
                    if(item['rolle'] == 'yt') {
                        res.redirect('http://localhost:80/YT_Welcome.html');
                    } else {
                        res.redirect('http://localhost:80/WT_Welcome.html');
                    }

                }
            });
        }
    );

    app.get('/logout', (req, res) => {
        req.logout();
        req.session.token = null;
        res.redirect('/');
    });

}

现在我想从我的前端发出一个POST请求到我的NodeJS后端。

前端请求:

function registerWT() {

    console.log('registerWT started...')

    var rolle = 'wt';

    var json = {"rolle": rolle};

    $.ajax({
        url: 'http://localhost:8000/user',
        type: 'POST',
        data: JSON.stringify(json),
        contentType: 'application/json; charset=utf-8',
        dataType: 'JSON',
        async: false,
        success: function (msg) {
            var js = JSON.stringify(msg);

            var state = msg['state']; 

            if (state == true) {
                console.log('successfully created new user')

            } else {

                console.log('failed to create new user')

            }

        }
    });

后端-API:

var ObjectID = require('mongodb').ObjectID;
const passport       = require('passport');
const passportInit  = require('./auth');

module.exports = (app, db) => {

    app.post('/user', (req, res) => {

        console.log("POST USER REACHED!"); // This is printed out...
        console.log(req.body.rolle); //is printed out correctly
        console.log(req.user); // Is undefined...

        if (!req.isAuthenticated()) { return res.send({'error':'unauthorized'}) } //Authentication fails...

        console.log(req.user.userId);
        console.log(req.userGivenName);
        console.log(req.body.rolle);

        userId = req.user.userId;
        userGivenName = req.user.userGivenName;
        userRolle= req.body.rolle;

        const details = { userId: userId, userGivenName: userGivenName, rolle: userRolle };

        db.collection('users').insert(details, (err, result) => {
          if (err) { 
            res.send({ 'error': 'An error has occurred' }); 
          } else {
            res.send(result.ops[0]);
          }
        });
    });

}

  

根据我的理解,我应该从我的前端到后端的每个请求自动发送用户身份验证数据,因为我之前通过谷歌登录。这是正确的还是我错过了在我的前端JS请求代码中包含一些内容?

什么是令人兴奋的是,在我登录后,我不得不导航到/ user。因此,manualy对此API执行get请求没有问题,我也在检查身份验证。

app.get('/user', (req, res) => {
       if (!req.isAuthenticated()) { return res.send({'error':'unauthorized'}) }
        db.collection('users').find({}).toArray((err, item) => {
            if (err) {
                res.send({'error':'An error has occurred'});
            } else {
                res.json(item)
            }
        });
    });

但是当我使用JavaScript发出Get请求时,身份验证再次失败......

JavaScript get request:

function getTest() {
    console.log('YT');

        $.ajax({
            url: 'http://localhost:8000/user',
            type: 'GET',
            async: false,
            success: function (msg) {
                var state = msg['state']; //nehmen den Wert von state aus der JSON

                if (state == true) {
                    console.log('successfully created new user')

                } else {

                    console.log('failed to create new user')
                }
            }

        });
}

有人知道我在做错了什么吗?

编辑: 我的passportInit

const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
const keys = require('../../config/keys')

module.exports = (passport) => {
    passport.serializeUser((user, done) => {
        done(null, user);
    });
    passport.deserializeUser((user, done) => {
        done(null, user);
    });
    passport.use(new GoogleStrategy({
        clientID: keys.google.clientID,
        clientSecret: keys.google.cientSecret,
        callbackURL: keys.google.callback
    },
    (token, refreshToken, profile, done) => {
        return done(null, {
            profile: profile,
            token: token
        });
    }));
};

Edit2:添加了cors包:

    const MongoClient    = require('mongodb').MongoClient;
    const bodyParser     = require('body-parser');
    const db             = require('./config/db');
    const keys           = require('./config/keys')
    const passport       = require('passport');
    const express        = require('express');
    const app            = express();
    const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
    const cors           = require('cors')

    const port = 8000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors({ origin: 'http://localhost' })); //configuring cors

MongoClient.connect(db.url, (err, database) => {
    if (err) return console.log(err)

    app.options('*', cors()) // enable pre-flight across-the-board
    require('./authenticate')(app, database,passport);
    require('./app/routes')(app, database, passport);

    app.listen(port, () => {
    console.log('We are live on ' + port);
    });
});  

1 个答案:

答案 0 :(得分:0)

我终于能够解决问题了。 不,需要浏览器插件或类似的东西! 请参阅下面的代码。

前端请求:

function register() {

    var role = 'wt';

    var json = {"role": role};

    $.ajax({
        url: 'http://localhost:8000/user',
        type: 'POST',
        data: JSON.stringify(json),
        contentType: 'application/json; charset=utf-8',
        dataType: 'JSON',
        xhrFields: {
            withCredentials: true
       },
       crossDomain: true,
       async: false,
       success: function (msg) {

            var state = msg['state']; 

            if (state == true) {
                console.log('successfully created new WT')
                location.href = 'http://localhost:80/WT_Welcome.html'

            } else {

                console.log('failed to create new WT')
                location.href = 'http://localhost:80/index.html'

            }

        }
    });
}    

Backend Server.js

const MongoClient    = require('mongodb').MongoClient;
const bodyParser     = require('body-parser');
const db             = require('./config/db');
const keys           = require('./config/keys')
const passport       = require('passport');
const express        = require('express');
const app            = express();
const GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;

const port = 8000;

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

MongoClient.connect(db.url, (err, database) => {
    if (err) return console.log(err)

    app.use(function(req, res, next) {
        res.header('Access-Control-Allow-Origin', "http://localhost");
        res.header('Access-Control-Allow-Methods','GET,PUT,POST,DELETE');
        res.header('Access-Control-Allow-Credentials', true)
        res.header('Access-Control-Allow-Headers', 'Content-Type');
        next();
    })

    require('./authenticate')(app, database,passport);
    require('./app/routes')(app, database, passport);

    app.listen(port, () => {
    console.log('We are live on ' + port);
    });
});   

后端API:

app.post('/user', (req, res) => {

        if (!req.isAuthenticated()) { return res.send({'error':'unauthorized'}) } //Authentication fails...

        userString = JSON.stringify(req.user);
        userObject = JSON.parse(userString)

        userId = userObjectValue['profile'].id;
        userName = userObjectValue['profile'].name; //not used
        userGivenName = userName.givenName;
        userRolle= req.body.rolle;

        const details = { userId: userId, userGivenName: userGivenName, rolle: userRolle };

        console.log(details);

        db.collection('users').insert(details, (err, result) => {
          if (err) { 
            res.send({ 'state': false }); 
          } else {
            res.send({'state' : true});
          }
        });
    });