我正在制作一个快速聊天应用,现在我正在从事聊天创建。为了创建聊天,您需要登录,但是我的会话不起作用,特别是当我想创建聊天时,令牌值只是未定义。在chat.js中是未定义的,在这里我在/ create处监听发布请求。
这是我的代码:
server.js
// server.js
// Main server file for BoaiChat
const express = require('express');
const app = express();
const port = 3000;
const utils = require('./tools.js');
const mongoose = require('mongoose');
var bodyParser = require('body-parser');
var url = "mongodb://localhost:27017/paperplane";
app.use(bodyParser.urlencoded({ extended: false }));
mongoose.connect(url, {useNewUrlParser: true});
var session = require('express-session');
app.use(session({ secret: utils.cookieSecret, cookie: { maxAge: utils.cookieAge }}));
// Define routers
const membership = require('./user.js');
const chat = require('./chat.js');
app.get('/', (req, res) => {
res.sendFile(utils.getFilePath('index.html'));
});
app.use('/membership', membership);
app.use('/chat', chat);
app.listen(port, () => console.log(`Application listening on port ${port}.`));
user.js
// user.js
// User.js is a router (mini-app) used to handle user creation and login.
const express = require('express');
const utils = require('./tools.js');
let router = express.Router();
var app = require('express')();
const mongoose = require('mongoose');
var bodyParser = require('body-parser')
var url = "mongodb://localhost:27017/paperplane";
mongoose.connect(url, {useNewUrlParser: true});
var session = require('express-session');
router.use(session({ secret: utils.cookieSecret, cookie: { maxAge: utils.cookieAge }}));
app.use(bodyParser.urlencoded({ extended: false }));
const bcrypt = require('bcrypt');
const saltRounds = 10;
// Logging
router.use(function timeLog (req, res, next) {
console.log('User router used: Time: ', Date.now());
next();
});
// Root for localhost/membership
router.get('/', function (req, res) {
res.sendFile(utils.getFilePath('user/home.html'));
});
// User creation handling:
router.get('/create', async (req, res) => {
res.sendFile(utils.getFilePath('user/create.html'));
});
router.post('/create', async (req, res) => {
let resp = await utils.validateUser(req.body.nickname, req.body.email, req.body.password);
if (resp.ok == true) {
let newpass = await utils.generatePassword(req.body.password);
console.log(newpass);
let newDocument = {username: req.body.nickname, email: req.body.email, password: newpass, joinedChats: []};
console.log(utils.newDocument(utils.User, newDocument));
res.send('User Created');
res.end();
} else {
res.send(resp.error.error);
res.end();
}
});
// User login handling
router.get('/login', async (req, res) => {
// Check if user is already logged in, if yes, go the the homepage (maybe do in html file)
res.sendFile(utils.getFilePath('user/login.html'));
});
router.post('/login', async (req, res) => {
let userDocument = await utils.getUserDataByUsername(req.body.nickname);
console.log(userDocument);
if (userDocument != false) {
const match = bcrypt.compareSync(req.body.password, userDocument.password);
if (match) {
let tok = utils.getTokenFromData({username: req.body.nickname, password: userDocument.password});
req.session.token = tok;
res.send("You are now logged in, "+req.body.nickname);
} else {
res.end('Invalid password.');
return 0;
}
} else {
res.end('User does not exist.');
return 0;
}
});
module.exports = router
tools.js
// Tools.js
// Tool functions for BoaiChat
const Joi = require('joi');
const mongoose = require('mongoose');
var url = "mongodb://localhost:27017/paperplane";
mongoose.connect(url, {useNewUrlParser: true});
var session = require('express-session');
const bcrypt = require('bcrypt');
const saltRounds = 10;
var session = require('express-session')
module.exports = {
root: __dirname + '/public/',
getFilePath: function(a) {
return this.root + a;
},
User: mongoose.model('User', new mongoose.Schema({
username: {
type: String,
required: true,
minlength: 3,
maxlength: 30
},
email: {
type: String,
required: true,
minlength: 5,
maxlength: 255,
unique: true
},
password: {
type: String,
required: true,
minlength: 16,
maxlength: 1024
},
joinedChats: {
type: Array
}
})),
Chat: mongoose.model('Chat', new mongoose.Schema({
owner: {
type: String,
required: true,
minlength: 3,
maxlength: 30
},
name: {
type: String,
required: true,
minlength: 5,
maxlength: 255
},
messages: {
type: Array
}
})),
validateUserObject: function(u) {
const schema = {
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(16).max(500).required()
};
return Joi.validate(u, schema);
},
userExists: async function(u, e) {
let emailCheck = await this.User.findOne({ email: e });
let userCheck = await this.User.findOne({ username: u });
if (emailCheck || userCheck) {
return true;
}
return false;
},
validateUser: async function(u, e, p) {
let userObject = {
username: u,
email: e,
password: p
};
let usernameValidation = module.exports.validateUserObject(userObject);
let userExistsValidation = await module.exports.userExists(u, e);
let retObject = {
error: usernameValidation,
userExists: userExistsValidation,
ok: true
}
if (retObject.error.error !== null) {
retObject.ok = false;
}
if (retObject.userExists == true) {
retObject.ok = false;
}
console.log(JSON.stringify(retObject));
return retObject;
},
newDocument: function(s, m) {
let ret;
let newDoc = new s(m);
newDoc.save(function(err){
ret = err;
});
return ret;
},
generatePassword: async function(p) {
let genPassword = await bcrypt.hash(p, saltRounds);
return genPassword;
},
checkPassword: async function(plain, hash) {
let isOk = await bcrypt.compare(plain, hash);
return isOk;
},
getUserDataByUsername: async function(u) {
let find = await this.User.findOne({ username: u });
if (find) {
return find;
}
return false;
},
getTokenFromData: function(data) {
return data.username+'_._'+data.password;
},
getDataFromToken: function(t) {
return t.split('_._');
},
validateToken: async function(t) {
let data = this.getDataFromToken(t);
if (data.length == 2 && data[0] && data[1]) {
let u = this.getUserDataByUsername(data[0]);
if (u) {
if (u.password == data[1]) {
return {valid: true, user: u};
}
}
}
return false;
},
cookieSecret: "60 character code I use",
cookieAge: 999999999
};
chat.js
// user.js
// User.js is a router (mini-app) used to handle user creation and login.
const express = require('express');
const utils = require('./tools.js');
let router = express.Router();
var app = require('express')();
const mongoose = require('mongoose');
var bodyParser = require('body-parser')
var url = "mongodb://localhost:27017/paperplane";
var session = require('express-session');
router.use(session({ secret: utils.cookieSecret, cookie: { maxAge: utils.cookieAge }}));
mongoose.connect(url, {useNewUrlParser: true});
app.use(bodyParser.urlencoded({ extended: false }));
const bcrypt = require('bcrypt');
const saltRounds = 10;
// Logging
router.use(function timeLog (req, res, next) {
console.log('Chat router used: Time: ', Date.now());
next();
});
// Root for localhost/chat
router.get('/', function (req, res) {
res.sendFile(utils.getFilePath('user/home.html'));
});
router.get('/create', async (req, res) => {
res.sendFile(utils.getFilePath('chat/create.html'));
});
router.post('/create', async (req, res) => {
let ret = 'Unknown error.';
let tok = req.session.token;
if (tok) {
let tokValid = await utils.validateToken(tok);
if (tokValid.valid == true) {
let chatDocument = {
owner: tokValid.user.username,
name: req.body.name
};
newDocument(utils.chat, chatDocument);
let newData = {
joinedChats: tokValid.user.joinedChat
};
let query = {
username: tokValid.user.username
};
await utils.user.findOneAndUpdate(query, newData, {upsert:true});
ret = 'Chat created.';
} else {
ret = 'Token invalid.';
}
} else {
ret = 'Token undefined.';
}
res.end(ret);
return 0;
});
module.exports = router
所有正在发送的html文件都是非常基本的文件,例如登录和创建只是表格