Я создаю страницу входа в систему, и проблема в том, что экспресс-создание нового сеанса происходит каждый раз, когда поступает запрос из приложения веб-интерфейса. Я проверил и попробовал все остальные ответы в сети и здесь, на 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