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> |