Simple example to write cookies using a Cloudfront distribution behavior with viewer-request trigger and lambda function.
Content:
- index.js (Lambda function)
- index.html (S3 bucket asset)
- error.html (S3 bucket asset)
- private.html (S3 bucket asset)
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Error Page</title> | |
</head> | |
<body> | |
<h1>Sorry your credentials are wrong...</h1> | |
</body> | |
</html> |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Home</title> | |
</head> | |
<body> | |
<h1>Login</h1> | |
<form method="POST" action="/login"> | |
<input type="text" name="username" required placeholder="Username"><br> | |
<input type="password" name="password" required placeholder="Password"><br> | |
<button type="submit">Login</button> | |
</form> | |
</body> | |
</html> |
const getDataDecoded = (data, encoding) => { | |
console.log('Getting data encoded with: ',encoding) | |
if(encoding === 'base64'){ | |
return Buffer.from(data,'base64').toString('utf-8') | |
} | |
return data | |
} | |
module.exports.handle = async event => { | |
console.log('Event: ', JSON.stringify(event)) | |
const request = event.Records[0].cf.request | |
let response = { | |
status: '302', | |
headers: { | |
location: [{ | |
key:'Location', | |
value: '/error.html' | |
}] | |
} | |
} | |
if (request.method === 'POST' && request.body.data) { | |
console.log('Encoded login data: ', request.body.data) | |
const data = getDataDecoded(request.body.data,request.body.encoding) | |
console.log('Decoded login data: ', data) | |
const credentials = data.split('&') | |
const username = credentials[0].split('=')[1] | |
const password = credentials[1].split('=')[1] | |
if (username === 'foo' && password === 'bar') { | |
console.log('Login successfully') | |
const token = Buffer.from([username, password].join(':')).toString('base64') | |
response = { | |
status: '302', | |
headers: { | |
location: [{ | |
key:'Location', | |
value: '/private.html' | |
}], | |
'set-cookie': [{ | |
key: 'Set-Cookie', | |
value: [ | |
['token', token].join('='), | |
'HttpOnly', | |
['Max-Age', (60 * 60)].join('=') | |
].join(';') | |
}] | |
} | |
} | |
} | |
} | |
console.log('Returning response: ',JSON.stringify(response)) | |
return response | |
} |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Welcome</title> | |
</head> | |
<body> | |
<h1>This a private page content</h1> | |
</body> | |
</html> |