Экспресс новый сеанс по запросу из приложения внешнего интерфейса - PullRequest
0 голосов
/ 07 января 2019

Я создаю страницу входа в систему, и проблема в том, что экспресс-создание нового сеанса происходит каждый раз, когда поступает запрос из приложения веб-интерфейса. Я проверил и попробовал все остальные ответы в сети и здесь, на SO. Больше всего меня беспокоит то, что он работает с curl, но не через приложение внешнего интерфейса. Вот код: server.js

const bodyParser = require('body-parser');
const cors = require('cors');
const session = require('express-session')
const cookieParser = require('cookie-parser');
const express = require('express');
const app = express();
app.use(cors());
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({extended: true})); // for parsing application/x-www-form-urlencoded
app.use(cookieParser('keyboard cat'));
app.set('trust proxy', true);
app.use(session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
    httpOnly: true,
    cookie: {secure: false}
}));

app.get('/secured', function (req, res) {
    res.header("Access-Control-Allow-Origin", "http://localhost:3006");
    res.header("Access-Control-Allow-Credentials", "true");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cookie");
    if (req.session) {
        console.log("has session", req.session);
        if (req.session.loggedInUser) {
            res.status(200).end("OK");
        } else {
            res.status(401).end("NOTOK1");
        }
    } else {
        res.status(401).end("NOTOK2");
    }
});

const users = [
    {email: 'foo@bar.com', pass: 'foo'}
];
app.post('/login', function (req, res) {
    const matched = users.filter(e => e.email === req.body.loginEmail && e.pass === req.body.loginPassword);
    if (matched === undefined || matched.length === 0) {
        res.status(401).end('NOTOK');
    } else {
        req.session.loggedInUser = matched[0];
        req.session.save();
        res.status(200).end('OK');
    }
});

app.listen(8000, () => {
    console.log('Started, listening');
});

И компонент входа из внешнего интерфейса (React).

import React from "react";
import {MDBBtn, MDBCol, MDBContainer, MDBRow} from 'mdbreact';
import axios from 'axios';

class Login extends React.Component {

    constructor(props) {
        super(props);
        this.state = {error:{}};
        this.handleLogin = this.handleLogin.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    handleLogin(event) {
        event.preventDefault();
        let state = this.state;
        let registerFormInputs = Object.keys(this.state).filter(v => v.startsWith("login"));
        const data = {};
        registerFormInputs.forEach(function (input) {
            data[input] = state[input];
        });
        axios.post('http://localhost:8000/login', data)
            .then(function (response) {
                axios.get('http://localhost:8000/secured', {withCredentials: true})
                    .then(resp => {
                        console.log(resp);
                    });
            })
            .catch(err => {
                this.setState({error: err.response})
            })

    }

    handleChange(event) {
        this.setState({[event.target.id]: event.target.value});
    }

    render() {
        return (
                <MDBContainer>
                    <MDBRow>
                        <MDBCol md="6">
                            <form onSubmit={this.handleLogin}>
                                <p className="h4 text-center mb-4">Log in</p>
                                {this.state.error.data ? <div>{this.state.error.data}</div> : null}
                                <label htmlFor="loginEmail" className="grey-text">
                                    Email
                                </label>
                                <input
                                    type="email"
                                    id="loginEmail"
                                    className="form-control"
                                    onChange={this.handleChange}
                                />
                                <br/>
                                <label htmlFor="loginPassword" className="grey-text">
                                    Password
                                </label>
                                <input
                                    type="password"
                                    id="loginPassword"
                                    className="form-control"
                                    onChange={this.handleChange}
                                />
                                <div className="text-center mt-4">
                                    <MDBBtn color="indigo" type="submit">Login</MDBBtn>
                                </div>
                            </form>
                        </MDBCol>
                    </MDBRow>
                </MDBContainer>
            );
    }
}

export default Login;

Интерфейс: https://codesandbox.io/s/2vor7xproj

Бэкэнд: https://codesandbox.io/s/j755x416j9

1 Ответ

0 голосов
/ 08 января 2019

Обычно я не обрабатываю сессии напрямую. Я позволил паспорту справиться с этим. Однако в конструкторе сеанса saveUninitialized обычно имеет значение false при работе с событиями входа в систему или при попытке обработки условий гонки в параллельных запросах.

Из экспресс-сессии npm saveUninitialized Принудительно "неинициализированный" сеанс сохраняется в хранилище. Сессия не инициализируется, когда она новая, но не изменена. Выбор false полезен для реализации сеансов входа в систему, сокращения использования хранилища на сервере или соблюдения законов, которые требуют разрешения перед установкой файла cookie. Выбор false также поможет в условиях гонки, когда клиент делает несколько параллельных запросов без сеанса.

Значением по умолчанию является true, но использование по умолчанию устарело, так как значение по умолчанию изменится в будущем. Пожалуйста, изучите этот параметр и выберите то, что подходит для вашего варианта использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...