当我在移动设备上打开我的网站时,没有创建Web会话



我有这个电子商务网站与节点,mongodb和express创建。它是托管在heroku和这是url: https://elisales.herokuapp.com/。登录是完美的桌面工作,但当我打开任何手机上的网站,登录不工作。您可以使用username: dee,密码:迪登录。

我在heroku上跟踪日志,有没有错误消息. 我将会话记录到控制台,发现结果是null当我在手机上打开它时,会话是在桌面上打开网站时创建的。我似乎找不到问题所在。任何帮助吗?这是我完成的第一个项目。

这是指向GitHub repo的链接:https://github.com/elijaharhinful/e-commerce

这是我的index.js的副本

require('dotenv').config();
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const config = require('./config/database')
const session = require('express-session')
const expressValidator = require('express-validator');
const fileUpload = require('express-fileupload');
const passport = require('passport');
const MongoStore = require('connect-mongo');
//conect to database
main().catch(err => console.log(err));
async function main() {
if (process.env.NODE_ENV === "development") {
await mongoose.connect(config.database)
console.log('Connected to MongoDB local')
} else if (process.env.NODE_ENV === "production") {
await mongoose.connect(process.env.MONGODB_URL)
console.log('Connected to MongoDB atlas')
}
}

//init app
let app = express();
//view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
//set public folder
//app.use(express.static('public'));
app.use(express.static(path.join(__dirname, 'public')));

//set global errors variable
app.locals.errors = null;
// Get Page Model
let Page = require('./models/page');
// Get all pages to pass to header.ejs
Page.find({}).sort({sorting: 1}).exec(function (err, pages) {
if (err) {
console.log(err);
} else {
app.locals.pages = pages;
}
});
// Get Category Model
let Category = require('./models/category');
// Get all categories to pass to header.ejs
Category.find(function (err, categories) {
if (err) {
console.log(err);
} else {
app.locals.categories = categories;
}
});
// Express fileUpload middleware
app.use(fileUpload());
//body parser middleware
app.use(express.urlencoded({ extended: false}))
app.use(express.json());
// Express Session middleware
if (process.env.NODE_ENV === "development"){
app.use(session({
secret: process.env.SESS_KEY,
resave: true,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: config.database,
ttl: 5 * 24 * 60 * 60 // = 5 days.
})
//  cookie: { secure: true }
}));
}else if (process.env.NODE_ENV === "production"){
app.set('trust proxy', 1); // trust first proxy
app.use(session({
secret: process.env.SESS_KEY,
resave: true,
saveUninitialized: true,
cookie: { secure: true },
store: MongoStore.create({
mongoUrl: process.env.MONGODB_URL,
ttl: 1 * 24 * 60 * 60 // = 1 day.
})
}));
}

// Express Validator middleware
app.use(expressValidator({
errorFormatter: function (param, msg, value) {
let namespace = param.split('.'),
root = namespace.shift(),
formParam = root;
while (namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg: msg,
value: value
};
},
customValidators: {
isImage: function (value, filename) {
let extension = (path.extname(filename)).toLowerCase();
switch (extension) {
case '.jpg':
return '.jpg';
case '.jpeg':
return '.jpeg';
case '.png':
return '.png';
case '':
return '.jpg';
default:
return false;
}
}
}
}));

//Express Messages middleware
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
// Passport Config
require('./config/passport')(passport);
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
app.get('*', function(req,res,next) {
res.locals.cart = req.session.cart;
res.locals.user = req.user || null;
next();
});
// Set routes 
const pages = require('./routes/pages.js');
const products = require('./routes/products.js');
const cart = require('./routes/cart.js');
const users = require('./routes/users.js');
const adminPages = require('./routes/admin_pages.js');
const adminCategories = require('./routes/admin_categories.js');
const adminProducts = require('./routes/admin_products.js');
const database = require('./config/database');
app.use('/admin/pages', adminPages);
app.use('/admin/categories', adminCategories);
app.use('/admin/products', adminProducts);
app.use('/products', products);
app.use('/cart', cart);
app.use('/users', users);
app.use('/', pages);
app.use(function (req, res) {
res.status(404);
res.render('404');
});
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500);
res.render('500');
});
//start the server
let PORT = process.env.PORT || 3000;
app.listen(PORT, function () {
console.log('App is running on http://localhost:' + PORT);
});

这是user。js

require('dotenv').config();
const express = require('express');
const router = express.Router();
const passport = require('passport');
const bcrypt = require('bcryptjs');
const async = require('async');
const crypto = require('crypto');
const nodemailer = require('nodemailer');
const { google } = require('googleapis');
const OAuth2 = google.auth.OAuth2
// Get Users model
let User = require('../models/user');
// Get Tokens model
let Token = require('../models/token');

const OAuth2_client = new OAuth2(process.env.CLIENT_ID, process.env.CLIENT_SECRET)
OAuth2_client.setCredentials( { refresh_token : process.env.REFRESH_TOKEN } )
const accessToken = OAuth2_client.getAccessToken()
/*
* GET register
*/
router.get('/register', function (req, res) {
res.render('register', {
title: 'Register'
});
});
/*
* POST register
*/
router.post('/register', function (req, res) {
let name = req.body.name;
let email = req.body.email;
let username = req.body.username;
let password = req.body.password;
let password2 = req.body.password2;
req.checkBody('name', 'Name is required!').notEmpty();
req.checkBody('email', 'Email is required!').isEmail();
req.checkBody('username', 'Username is required!').notEmpty();
req.checkBody('password', 'Password is required!').notEmpty();
req.checkBody('password2', 'Passwords do not match!').equals(password);
let errors = req.validationErrors();
if (errors) {
res.render('register', {
errors: errors,
user: null,
title: 'Register'
});
} else {
User.findOne({
username: username
}, function (err, user) {
if (err)
console.log(err);
if (user) {
req.flash('danger', 'Username exists, choose another!');
res.redirect('/users/register');
} else {
let user = new User({
name: name,
email: email,
username: username,
password: password,
admin: 0
});
bcrypt.genSalt(10, function (err, salt) {
bcrypt.hash(user.password, salt, function (err, hash) {
if (err)
console.log(err);
user.password = hash;
user.save(function (err) {
if (err) {
console.log(err);
} else {
crypto.randomBytes(16, function (err, buf) {
if (err) console.log(err);
let token = new Token({
_userId: user.id,
token: buf.toString('hex')
});
token.save(function (err) {
if (err) {
console.log(err);
} else {
async function main() {
//let testAccount = await nodemailer.createTestAccount();
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
type: 'OAuth2',
user: process.env.MAIL_USERNAME, // generated ethereal user
pass: process.env.MAIL_PASSWORD,
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
refreshToken: process.env.REFRESH_TOKEN,
accessToken: accessToken
},
});
// send mail with defined transport object
await transporter.sendMail({
from: '"My Website 👻"elijaharhinful8@gmail.com', // sender address
to: user.email, // list of receiver (s)
subject: "Verify your My Website email", // Subject line
text: 'Hello ' + user.username + ',nn' +
'Thanks for signing up with My Website! Before you get started, we need you to confirm your email address. Please click the link below to complete your signup.nn' +
'http://' + req.headers.host + '/users/confirm-email/' + token.token + 'nn' +
'If you have any trouble clicking the link, please copy and paste the URL into your prefered web browser.nn' +
'If you did not request this, please ignore this email.n' // html body
});
req.flash('info', 'A verification e-mail has been sent to ' + user.email + ' with further instructions.');
res.redirect('/users/register-token')
}
main().catch(console.error);
}
});
});
}
});
});
});
}
});
}
});


/*
* GET login
*/
router.get('/login', function (req, res) {
if (res.locals.user) res.redirect('/');
res.render('login', {
title: 'Log in'
});
});
/*
* POST login
*/
router.post('/login', function (req, res, next) {
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/users/login',
isVerified: '/users/login',
failureFlash: true
})(req, res, next);
});
/*
* GET logout
*/
router.get('/logout', function (req, res) {
req.logout();
req.flash('success', 'You are logged out!');
res.redirect('/users/login');
});

我找到了一个解决方案!问题是我设置了"cookie安全"选项"true"。在桌面上,网站打开了"https://"因此,饼干工作得很完美。在手机上,它会打开"http://"这是一个问题,因为安全cookie不能通过不安全的url发送。

解决方案是替换"http://"与"https://"在手机上输入网址的时候,那就解决了。

阅读更多:https://www.npmjs.com/package/express-session