的NodeJS。在React的客户端登录后无法获取凭据

时间:2018-04-10 22:19:24

标签: node.js mongodb express cookies express-session

我试图了解我的服务器代码中的credetrials有什么问题,因为当我从客户端进行登录时,credetrials不会在router.get('/auth/login')方法中重新定义,但当我使用POST方法通过邮递员执行相同的登录操作,然后使用GET方法重新加载页面时credetrials正常重新编译,我得到了消息,我已经loggined

所以,我实际上想说,通过&#34; POST&#34;来自客户端的loginnig我没有任何问题。 router.post('/auth/login')的方法,对于日志 - 用户信息正常传输,凭据也会创建,但在router.get('/auth/login')上它不会在res.json({session: req.session.userId, session2: req.session, log: 'You already logined!'});中回调,我只得到空字符串... < / p>

我的服务器代码:

'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;

1 个答案:

答案 0 :(得分:1)

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

默认情况下,AJAX调用不会在CORS环境中发送cookie。您需要将 XMLHttpRequest 对象的 withCredentials 字段设置为 true ,才能发送Cookie甚至跨域。 Here是官方文件。

当您使用 axios 时,希望此设置会有所帮助。

  

axios.defaults.withCredentials = true;

<强>更新

请更新您的客户端代码并确保在 POST / auth / login 完成后请求 GET / auth / login ,否则获取 POST 请求未完成身份验证并设置会话时,可能会发送请求。我建议您更改以下代码(在 POST 请求解决后输入获取请求):

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);
        });

```