Sunday, 7 May 2017

EJS and connect-flash doesn't work as expected

I'm trying to wrap my brain around templates and flash messages using EJS and connect-flash along with express and express-session, but I can't seem to get it to work the way I want or expected.

When I define a flash message I console.log it, and I can see it just fine. But when I try to print it in my template, req.flash is an empty object [object Object].

The flash message in console.log after failed login attempt:

flash(): { error: [ 'Brugernavn eller adgangskode er ikke korrekt.' ] }

But when I try to loop through flash in my ejs template with something like

<% flash.forEach(function (message) { %>
    <p><%=message%></p>
<% }) %>

The above returns an error on

TypeError: C:\path\to\my\stuff\auth-test\views\login.ejs:7
    [snippet with line indicator, not important]
flash.forEach is not a function

server.js

const myExpress = require('express')
const myApp = myExpress()
const myBodyParser = require('body-parser')
const flash = require('connect-flash')
const mySession = require('express-session')
const myLogger = require('morgan')
const myFs = require('fs')
const myPath = require('path')
const myEjs = require('ejs')
const myLRU = require('lru-cache')
const myAccessLogStream = myFs.createWriteStream(myPath.join(__dirname, 'logs', 'access.log'), { flags: 'a' })
const myPort = process.env.PORT || 1337

const myAuthCheck = function (myRequest) {
    if (!myRequest.session || !myRequest.session.authenticated) {
        return false
    }
    else {
        return true
    }
}

myApp.engine('ejs', require('express-ejs-extend'))
myApp.set('view engine', 'ejs')

myEjs.cache = myLRU(100)

myApp.use(flash())
myApp.use(mySession({ secret: 'meget hemmelig streng', resave: true, saveUninitialized: true }))

myApp.use(myBodyParser.urlencoded({'extended': 'true', limit: '50mb'}))
myApp.use(myBodyParser.json())
myApp.use(myBodyParser.json({ type: 'application/vnd.api+json', limit: '50mb' }))

myApp.use(myLogger('combined', { stream: myAccessLogStream }))

var hourMs = 1000 * 60 * 60
myApp.use(myExpress.static(__dirname + '/public', { maxAge: hourMs }))

require('./routers/frontendRouter')(myApp, myAuthCheck)

myApp.listen(myPort)

console.log('Serveren kører på http://localhost:' + myPort)

frontendRouter.js

(pay notice to the .post and .get routes for '/login')

const fetch = require('node-fetch')

module.exports = function (myApp, myAuthCheck) {

    myApp.get('/', function (myRequest, myResponse) {
        myResponse.render('home', { title: 'Hello, World!', data: 'Something wicked this way comes!' })
    })

    myApp.get('/test', function (myRequest, myResponse) {
        myResponse.render('article', { title: 'Dette er en test', data: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolor veniam voluptatibus vel omnis nostrum maiores, placeat! Nam ea asperiores, sint, aut reprehenderit eos, facere ipsum in, ratione sunt ab fugiat?'})
    })

    myApp.get('/profile', function (myRequest, myResponse) {
        if (!myAuthCheck(myRequest)) {
            myResponse.render('403', { title: 'Adgang forbudt', status: 403 })
        }
        else {
            myResponse.render('profile', { title: 'Profil' })
        }
    })

    myApp.post('/login', function (myRequest, myResponse) {
        if (myRequest.body.username && myRequest.body.username === 'admin' && myRequest.body.password && myRequest.body.password === '1234') {
            myRequest.session.authenticated = true
            myResponse.redirect('/profile')
        }
        else {
            myRequest.flash('error', 'Brugernavn eller adgangskode er ikke korrekt.')
            console.log('flash():', myRequest.flash())
            myResponse.redirect('/login')
        }
    })

    myApp.get('/login', function (myRequest, myResponse) {
        myResponse.render('login', { title: 'Log ind', flash: myRequest.flash() })
    })

    myApp.get('/logout', function (myRequest, myResponse) {
        delete myRequest.session.authenticated
        myResponse.redirect('/')
    })

}

login.ejs

<% extend('layout') %>
<section>
    <h1><%=title%></h1>
    <form action="" method="post">
        <p><input type="text" name="username" placeholder="Brugernavn"></p>
        <p><input type="password" name="password" placeholder="Adgangskode"></p>
        <% flash.forEach(function (message) { %>
            <p><%=message%></p>
        <% }) %>
        <button type="submit">Log ind</button>
    </form>
</section>



via Brian Emilius

No comments:

Post a Comment