Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use res.render or res.redirect with Express and EJS?

I'm very new to this topic. I would like to learn more about when to use render and redirect. The goal is to get my user to another page after they click a button or log in. This new page needs data so I'm passing this data during the render command. This is working fine except that the page URL does not represent the correct page that they are currently viewing. This being the case I'm wondering if I should be doing a redirect. Below is my code. This is a snippet of code for my server.js page

    // route for user Login
app.route('/login')
    .get(sessionChecker, (req, res) => {
        res.render('login');
    })
    .post((req, res) => {
        var username = req.body.username,
            password = req.body.password;

        User.findOne({ where: { username: username } }).then(function (user) {
            if (!user) {
                res.render('login');;
            } else if (!user.validPassword(password)) {
                res.render('login');;
            } else {
                req.session.user = user.dataValues;
                res.render('dashboard',{
                    "token" :  createToken(req),
                    "user" : req.session.user
                 });
            }
        });
    });

This is a snippet of code from my .ejs page

<% if( typeof user !== "undefined") { %>

                    <li><a href="/dashboard">Dashboard</a></li>
                    <li><a href="/reports">My Reports</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">Action</a></li>
                            <li><a href="#">Another action</a></li>
                            <li><a href="#">Something else here</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">Separated link</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">One more separated link</a></li>
                        </ul>
                    </li>

                    <% } %>

This is the full code from my server.js page.

var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var morgan = require('morgan');
var User = require('./models/user');
var crypto = require('crypto');

// invoke an instance of express application.
var app = express();

// set our application port
app.set('port', 9000);

app.set('view engine', 'ejs');
app.set('views', 'views');

// set morgan to log info about our requests for development use.
app.use(morgan('dev'));

// initialize body-parser to parse incoming parameters requests to req.body
app.use(bodyParser.urlencoded({ extended: true }));

// initialize cookie-parser to allow us access the cookies stored in the browser. 
app.use(cookieParser());

// initialize express-session to allow us track the logged-in user across sessions.
app.use(session({
    key: 'user_sid',
    secret: 'somerandonstuffs',
    resave: false,
    saveUninitialized: false,
    cookie: {
        expires: 600000
    }
}));


// This middleware will check if user's cookie is still saved in browser and user is not set, then automatically log the user out.
// This usually happens when you stop your express server after login, your cookie still remains saved in the browser.
app.use((req, res, next) => {
    if (req.cookies.user_sid && !req.session.user) {
        res.clearCookie('user_sid');        
    }
    next();
});


// middleware function to check for logged-in users
var sessionChecker = (req, res, next) => {
    if (req.session.user && req.cookies.user_sid) {
        res.render(req.originalUrl.substr(1, req.originalUrl.length),{
            "token" :  createToken(req),
            "user" : req.session.user
         });
    } else {
        next();
    }    
};

// route for Home-Page
app.get('/', sessionChecker, (req, res) => {
    res.redirect('/login');
});


// route for user signup
app.route('/signup')
    .get(sessionChecker, (req, res) => {
        //res.sendFile(__dirname + '/public/signup.html');
        res.render('signup');
    })
    .post((req, res) => {
        User.create({
            username: req.body.username,
            email: req.body.email,
            password: req.body.password,
            roles: req.body.roles
        })
        .then(user => {
            req.session.user = user.dataValues;
            res.render('dashboard',{
                "token" :  createToken(req),
                "user" : req.session.user
             });
        })
        .catch(error => {
            res.render('signup');
        });
    });


// route for user Login
app.route('/login')
    .get(sessionChecker, (req, res) => {
        res.render('login');
    })
    .post((req, res) => {
        var username = req.body.username,
            password = req.body.password;

        User.findOne({ where: { username: username } }).then(function (user) {
            if (!user) {
                res.redirect('/login');;
            } else if (!user.validPassword(password)) {
                res.redirect('/login');;
            } else {
                req.session.user = user.dataValues;
                res.render('dashboard',{
                    "token" :  createToken(req),
                    "user" : req.session.user
                 });
            }
        });
    });


// route for user's dashboard
app.get('/dashboard', (req, res) => {
    if (req.session.user && req.cookies.user_sid) {

        res.render('dashboard',{
           "token" : createToken(req),
           "user" : req.session.user
        });
    } else {
        res.render('login');
    }
});

// route for user's reports
app.get('/reports', (req, res) => {
    if (req.session.user && req.cookies.user_sid) {

        res.render('reports',{
           "token" : createToken(req),
           "user" : req.session.user
        });
    } else {
        res.render('login');
    }
});

// route for user's profile
app.route('/user_profile')
.get(sessionChecker, (req, res) => {
    res.render('user_profile');
})
.post((req, res) => {
    var username = req.body.username,
        password = req.body.password;

    User.findOne({ where: { username: username } }).then(function (user) {
        if (!user) {
            res.render('login');;
        } else if (!user.validPassword(password)) {
            res.render('login');;
        } else {
            req.session.user = user.dataValues;
            res.render('dashboard',{
                "token" :  createToken(req),
                "user" : req.session.user
             });
        }
    });
});

// route for user logout
app.get('/logout', (req, res) => {
    if (req.session.user && req.cookies.user_sid) {
        res.clearCookie('user_sid');
        res.render('login');;
    } else {
        res.render('login');;
    }
});




// route for handling 404 requests(unavailable routes)
app.use(function (req, res, next) {
  res.status(404).send("Sorry can't find that!")
});


// start the express server
app.listen(app.get('port'), () => console.log(`App started on port ${app.get('port')}`));

function createToken(req){
    var data = 'u=' + req.session.user.username + "|o=organization_1";  

    if (req.session.user.roles.length > 0){
        data += "|r=" + req.session.user.roles;
    }

    var buff = new Buffer(data);  
    var base64data = buff.toString('base64');

    console.log(base64data);  

    return base64data
}
like image 351
user179981 Avatar asked Dec 04 '22 20:12

user179981


1 Answers

res.redirect(someURL) is for you want to return a 30x status code (often 302) to the browser and tell the browser to go to a new URL. This is often done on the server as part of a login process and occasionally when the user finds themselves at an old URL that has been changed to something different. res.redirect() should only be used for these types of forced navigation to a different URL and should never be part of any standard rendering process.

res.render(filename, data) is how one would typically use EJS (or any other template engine plugged into Express) to fill in a template with some data and return the "rendered" HTML page back to the requesting browser so the browser can render it.


In the specific case you show in your question, when you "approve" the login, you may then want to do a res.redirect() to whatever URL you want the user to start on after the login and then create a route for that URL which you will use res.render() to render that page.

The steps will then look like this:

  1. User goes to /login.
  2. User submits login data with form POST.
  3. Server validates data and establishes login session.
  4. Server does res.redirect('/home') (or whatever URL you want here) to tell the browser to go to the new URL.
  5. Browser processes the redirect and sends request for that new page.
  6. Server sees request for the new page and uses res.render() to render the data for that page.
  7. Browser displays rendered page on the new URL.
like image 54
jfriend00 Avatar answered Dec 29 '22 01:12

jfriend00