节点JS。在 React 客户端进行身份验证登录后无法获取凭据

NodeJS. Cannot get Credentials after auth login on client-side of React

我试图了解我的服务器代码中的 credetrials 出了什么问题,因为当我从客户端登录时,credetrials 没有在 router.get('/auth/login') 方法,但是当我使用 PostmanPOST 方法执行相同的登录操作,然后使用 GET 方法重新加载页面时,credetrials 重新识别通常我收到消息说我已经 loggined.

所以,我真的想说,对于 router.post('/auth/login'),通过 "POST" 方法从客户端登录我没有任何问题,至于日志 - 用户信息和凭据正常传输也会创建,但在 router.get('/auth/login') 上它不会在 res.json({session: req.session.userId, session2: req.session, log: 'You already logined!'}); 中回调,我在那里得到的只是空字符串...

我的服务器代码:

'use strict'
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
const bcrypt = require('bcrypt-nodejs');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);

const app = express();
const router = express.Router();

const EmployersSchemaDB = require('./SchemaDB/EmployersSchemaDB');
const User = require('./SchemaDB/ShemaAuthtificaion');

mongoose.connect('mongodb://myDB');

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

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers');
    res.setHeader('Cache-Control', 'no-cache');
    next();
});

app.use(session({
    secret: 'work hard',
    resave: true,
    saveUninitialized: false,
    store: new MongoStore({ mongooseConnection: mongoose.connection })
}));

router.get('/', (req, res) => {
    res.json('Hello on Homepage!');
});

router
    .get('/auth/login', (req, res) => {
        User.find((err, users) => {
            if (err) { res.send(err) }
            if (req.session.userId !== undefined) { // there is where I always falls...
                res.json({session: req.session.userId, session2: req.session, log: 'You already logined!'});
            } else {
                console.log('User credentials!:', req.session.userId);
                res.json({session: req.session.userId, session2: req.session});
                console.log('---===--- \n Employers showed!: \n', users + '\n ---===---');
            }
        });
    })
    .post('/auth/login', (req, res, next) => {
        if (req.body.password !== req.body.passwordConf) {
            var err = new Error('Passwords do not match.');
            err.status = 400;
            res.send("passwords dont match");
            return next(err);
        }

        if (req.body.email &&
            req.body.username &&
            req.body.password &&
            req.body.passwordConf) {

            let user = new User();

            user.email = req.body.email;
            user.username = req.body.username;
            user.password = req.body.password;
            user.passwordConf = req.body.passwordConf;

            user.save((err) => {
                if (err) { res.send(err) }

                res.json({ message: 'Comment successfully added!', user });
                console.log('---===--- \n Employer added: \n', user + '\n ---===---');
            });  
        } else if (req.body.logemail && req.body.logpassword) {
            User.authenticate(req.body.logemail, req.body.logpassword, function (error, user) {
                if (error || !user) {
                var err = new Error('Wrong email or password.');
                err.status = 401;
                return next(err);
              } else { // this is the where credentials are creates. All work good! 
                req.session.userId = user._id;
                console.log('Signed Cookies: ', req.session.userId, req.signedCookies)
                console.log('User logined and redirected!');
                return res.redirect('/employers');
              }
            });
        } else {
            var err = new Error('All fields required.');
            err.status = 400;
            return next(err);
        }
    });

app.use('/', router);

const port = process.env.API_PORT || 3016;
app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

我的客户端代码(仅供参考):KEVIN 更新

import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import axios from 'axios';

class LoginPage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            navigate: false
        }
    }

    handleSubmit = (e) => {
        e.preventDefault();

        let userLogin = {
            logemail: e.target.email.value,
            logpassword: e.target.password.value
        }

        axios.post('http://localhost:3016/auth/login', userLogin)
            .then(function(){
                axios.get('http://localhost:3016/auth/login', {withCredentials: true})
                    .then(res => console.log(res.data))
                    .catch(err => console.log(err)); 
                this.setState({
                    navigate: true
                })
            })
            .catch(err => {
                console.error(err);
            });
    };
    render() {
        // if (this.state.navigate) {
        //   return <Redirect to="/employers" />
        // }
        return (
            <form onSubmit={this.handleSubmit}>
                <div className="form-group">
                    <label htmlFor="exampleInputEmail1">Email address</label>
                    <input name="email" type="email" className="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email" />
                    <small id="emailHelp" className="form-text text-muted">We'll never share your email with anyone else.</small>
                </div>
                <div className="form-group">
                    <label htmlFor="exampleInputPassword1">Password</label>
                    <input name="password" type="password" className="form-control" id="exampleInputPassword1" placeholder="Password" />
                </div>
                <div className="form-check">
                    <input type="checkbox" className="form-check-input" id="exampleCheck1" />
                    <label className="form-check-label" htmlFor="exampleCheck1">Check me out</label>
                </div>
                <button type="submit" className="btn btn-primary">Submit</button>
            </form>
        )
    }
}

export default LoginPage;

这可能是一个跨域问题,您可以使用 Postman 成功登录。

AJAX 调用默认不会在 CORS 环境下发送 cookie。您需要将 XMLHttpRequest 对象的 withCredentials 字段设置为 true 以跨域发送 cookie。 Here是官方文档。

由于您正在使用 axios,希望此设置对您有所帮助。

axios.defaults.withCredentials = true;

更新:

请更新您的客户端代码并确保在 POST /auth/login[=36 之后请求 GET /auth/login =] 完成,否则 Get 请求可能会在 POST 请求尚未完成身份验证和设置会话时发送。我建议您像下面这样更改代码(在 POST 请求得到解决后提出 Get 请求):

axios.post('http://localhost:3016/auth/login', userLogin)
        .then(function(){
            axios.get('http://localhost:3016/auth/login').then(res => console.log(res.data).catch(e => console.log(e)); 
            this.setState({
                navigate: true
            })
         })
        .catch(err => {
            console.error(err);
        });

```