【问题标题】:Web session is not created when I open my website on a mobile device在移动设备上打开我的网站时未创建 Web 会话
【发布时间】:2021-10-25 23:57:52
【问题描述】:

我用 node、mongodb 和 express 创建了这个电子商务网站。它托管在 heroku 上,这是 url:https://elisales.herokuapp.com/。登录在桌面上完美运行,但是当我在任何手机上打开网站时,登录不起作用。 您可以使用 username : dee & password: dee 登录。

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

这是 GitHub 存储库的链接: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 + ',\n\n' +

                                                        '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.\n\n' +
                                                        'http://' + req.headers.host + '/users/confirm-email/' + token.token + '\n\n' +

                                                        'If you have any trouble clicking the link, please copy and paste the URL into your prefered web browser.\n\n' +

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

});

【问题讨论】:

    标签: node.js express session mobile


    【解决方案1】:

    我找到了解决办法!!! 问题是我已将“cookie 安全”选项设置为“true”。在桌面上,网站以“https://”打开,因此 cookie 运行良好。在手机上,它以“http://”打开,这是一个问题,因为无法通过不安全的 url 发送安全 cookie。

    解决方法是在手机上输入网址时将“http://”替换为“https://”即可解决。

    在此处阅读更多信息:https://www.npmjs.com/package/express-session

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多