Reputation: 284
Using the Hapijs Node framework, I want to ensure a certain cookie exists for each request. If it doesn't exist, I want to create it. I'd like to do this without manually adding that cookie to each reply
. For example, something like this:
server.ext('onPreHandler', function (request, reply) {
console.log(`state: ${JSON.stringify(request.state)}`) // state == null
request.state['my_cookie'] = request.state.my_cookie || 'my data'
return reply.continue();
});
server.route({
method: 'GET',
path: '/',
handler: function(request, reply) {
// includes `my_cookie`
reply(`Cookies: ${JSON.stringify(request.state)}`);
}
})
// cookie does not exist in the browser
Adding that cookie to the reply works, but will require adding to every reply across the app.
server.route({
method: 'GET',
path: '/',
handler: function(request, reply) {
reply(`Cookies: ${JSON.stringify(request.state)}`).state('my_cookie', 'my_data');
}
})
// cookie now exists in the browser
How can I ensure that a cookie is added to all requests, without manually adding a cookie to each reply?
Upvotes: 3
Views: 2514
Reputation: 461
hapi provides you with the functionality to use cookies out of the box.
At first, you need to prepare your server for a specific cookie:
const Hapi = require('hapi')
// create new server instance
const server = new Hapi.Server()
server.state('session', {
ttl: 1000 * 60 * 60 * 24, // 1 day lifetime
encoding: 'base64json' // cookie data is JSON-stringified and Base64 encoded
})
Afterwards, you can set your cookies using the reply
interface. This can be in a route handler or a plugin extending the request lifecycle.
Extend the request lifecylce (plugins are a good use-case for that)
The sample code below extends hapi’s request lifecycle and with that is processed on every request
server.ext('onRequest', function (request, reply) {
if (!request.state.cookie_name) {
reply.state('session', {your: 'cookie_data'})
}
reply.continue()
})
Route handler
server.route({
method: 'GET',
path: '/',
config: {
handler: function (request, reply) {
const cookie = {
lastVisit: Date.now()
}
reply('Hello Future Studio').state('session', cookie)
}
}
})
Read the cookie like this:
const cookie = request.state.session
You can read more on cookies and how to keep states across requests, in this guide.
Hope that helps!
Upvotes: 4
Reputation: 284
I was ultimately able to do this with server.ext
.
server.ext('onPreHandler', function (request, reply) {
request.state.my_cookie || reply.state('my_cookie', 'my value')
reply.continue();
});
Upvotes: 2