2

I am trying to set up user authentication in nodejs. I am using embedded js as the view engine.

I am trying to show a different template for whether the user is logged in or not. I viewed this page to determine if the user is logged in or not

How to know if user is logged in with passport.js?

In the header partial, I would like users to only see the login and register links if they are not logged in. I included this ejs.

<header>
    <% include header %>
</header>

And then in my header partial, I had this

<ul class="nav navbar-nav">
    <% if (!req.user) {%>
        <li><a href='login.ejs'>Login</a></li>
        <li><a href='register.ejs'>Register</a></li>
    <% } %>
</ul>

Here is my routes.js file

module.exports = function(app) {

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

    app.use(express.static(path.resolve('shapes')));

    app.get('/', function(req, res) {
        res.render(path.resolve('shapes/index'));
    });

    passport.serializeUser(function(user, done) {
        done(null, user);
    });

    passport.deserializeUser(function(user, done) {
        done(null, user);
    });

    passport.use(new LocalStrategy(function(username, password, done) {
        process.nextTick(function() {
            UserDetails.findOne({
                'username': username, 
            }, function(err, user) {
                if (err) {
                    return done(err);
                }

                if (!user) {
                    return done(null, false);
                }

                if (user.password != password) {
                    return done(null, false);
                }

                return done(null, user);
            });
        });
    }));

    app.get('/login', function(req, res) {
        res.sendFile(path.resolve('shapes/login.ejs'));
    });

    app.get('/register', function(req, res) {
        res.sendFile(path.resolve('shapes/register.ejs'));
    });

    app.post('/login', passport.authenticate('local', {
        successRedirect: '/',
        failureRedirect: '/login'
    }));

    app.get('/logout', function(req, res){
        req.logout();
        res.redirect('/');
    });

    function isLoggedIn(req, res, next) {

        // if user is authenticated in the session, carry on 
        if (req.isAuthenticated())
            return next();

        // if they aren't redirect them to the home page
        res.redirect('/');
    }

};

I reloaded the server and get that req is not defined.

The problem seems to be including this variable in my header partial.

Community
  • 1
  • 1
Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87

1 Answers1

2

In order to expose a variable to your template you have to pass it. e.g.

res.render(path.resolve('shapes/index'), {req: req});

The above will expose req to the template. However, you should not expose your complete req object to the template. You could simply pass an object with all the properties you want to have in the specific template.

e.g.

{ loggedin: true, username: 'someone' }

or something in the above lines.

Then in your template you can check

if (!loggedin) {
    // show here the login and register partial, etc.
}
x_maras
  • 2,177
  • 1
  • 25
  • 34
  • Thanks for your answer. However, I passed the req parameter to my `app.get('/')` block, but I still receive the same message. Am I missing something? – Richard Hamilton Jan 31 '16 at 18:31
  • Look the second example. If you pass the req object then you can access `user` and not `req.user`. You are passing an object and its properties are exposed in the template. Now I see that it is not 100% clear in my response. I will edit my answer so it's not confusing anymore. – x_maras Jan 31 '16 at 18:32
  • Passing in the object seems to solve this problem. But I think your second solution was better – Richard Hamilton Jan 31 '16 at 18:37