我在Symfony Web应用程序前面使用CloudFront作为缓存.要根据用户的角色(管理员,客户……)获取缓存,我会在Lambda @ Edge Viewer请求触发器中生成基于用户角色的哈希.我将该哈希作为请求标头传递给我的源X-User-Context-Hash.
我现在的问题是我需要将PHPSESSID cookie传递给我的来源以获得正确的缓存响应,但我不想将缓存基于PHPSESSID的值.我只需要我的缓存响应基于X-User-Context-Hash的值而不是我的会话cookie.
下面的图片应该详细解释我的问题
有没有可能实现这一目标?
非常感谢任何帮助.
这是我的Lambda @ Edge Viewer请求触发器:
- 'use strict';
- function parseCookies(headers) {
- const parsedCookie = {};
- if (headers.cookie) {
- console.log(`${headers.cookie[0].value}`);
- headers.cookie[0].value.split(';').forEach((cookie) => {
- if (cookie) {
- const parts = cookie.split('=');
- parsedCookie[parts[0].trim()] = parts[1].trim();
- }
- });
- }
- return parsedCookie;
- }
- exports.handler = (event,context,callback) => {
- const request = event.Records[0].cf.request;
- const headers = request.headers;
- const https = require('https');
- // Read session cookie
- const parsedCookies = parseCookies(headers);
- let cookie = '';
- if (parsedCookies) {
- if(parsedCookies['PHPSESSID']) {
- cookie = `PHPSESSID=${parsedCookies['PHPSESSID']}`;
- }
- }
- console.log(`Cookie: ${cookie}`);
- // Send request to origin host at /_fos_user_context_hash
- // passing the original session cookie
- const options = {
- hostname: `${request.headers.host[0].value}`,port: 443,path: '/_fos_user_context_hash',method: 'HEAD',headers: {
- 'Cookie': cookie,'Accept': 'application/vnd.fos.user-context-hash','Vary' : 'Cookie'
- }
- };
- const req = https.request(options,(res) => {
- console.log('statusCode:',res.statusCode);
- console.log('headers:',res.headers);
- // Read the X-User-Context-Hash from the hash endpoint
- const headerName = 'X-User-Context-Hash';
- let hash = 'anonymous';
- if (res.headers[headerName.toLowerCase()]) {
- hash = res.headers[headerName.toLowerCase()];
- }
- // Append X-User-Context-Hash before passing request on to CF
- request.headers[headerName.toLowerCase()] = [{ key: headerName,value: hash }];
- callback(null,request);
- }).on('error',(e) => {
- console.error(e);
- // Forward request anyway
- callback(null,request);
- });
- req.end();
- }
- ;
解决方法
这是我最终解决了我的问题:
CloudFront行为
我将行为配置为不将任何cookie转发到源,但仅基于头部主机和X-User-Context-Hash进行缓存(参见屏幕截图).
>在“查看器请求”触发器中,我读取了名为PHPSESSID和REMEMBERME的基于用户的cookie,并通过X-Session-Cookies标头传递这些值.
>如果我的请求URL和给定的主机以及X-User-Context-Hash标头匹配,则Cloud-Front将返回缓存的项目并在此处停止.
>如果没有匹配,则触发“Origin Request”触发器.当该事件触发自定义标头时,X-Session-Cookies可用.因此,我从X-Session-Cookies标头中获取值,并将request.headers.cookie的值设置为该值.此步骤确保PHPSESSID和REMEMBERME cookie在页面缓存之前都传递到源.
我的Lambda @ Edge功能:
查看者请求触发器:
- 'use strict';
- function parseCookies(headers) {
- const parsedCookie = {};
- if (headers.cookie) {
- console.log(`${headers.cookie[0].value}`);
- headers.cookie[0].value.split(';').forEach((cookie) => {
- if (cookie) {
- const parts = cookie.split('=');
- parsedCookie[parts[0].trim()] = parts[1].trim();
- }
- });
- }
- return parsedCookie;
- }
- exports.handler = (event,callback) => {
- const request = event.Records[0].cf.request;
- const headers = request.headers;
- const https = require('https');
- let sessionId = '';
- // Read session cookie
- const parsedCookies = parseCookies(headers);
- let cookie = '';
- if (parsedCookies) {
- if(parsedCookies['PHPSESSID']) {
- cookie = `PHPSESSID=${parsedCookies['PHPSESSID']}`;
- }
- if(parsedCookies['REMEMBERME']) {
- if (cookie.length > 0) {
- cookie += ';';
- }
- cookie += `REMEMBERME=${parsedCookies['REMEMBERME']}`;
- }
- }
- console.log(`Cookie: ${cookie}`);
- // Send request to origin host at /_fos_user_context_hash
- // passing the original session cookie
- const options = {
- hostname: `${request.headers.host[0].value}`,value: hash }];
- const sessionHeaderName = 'X-Session-Cookies';
- request.headers[sessionHeaderName.toLowerCase()] = [{ key: sessionHeaderName,value: cookie }];
- callback(null,request);
- });
- req.end();
- }
- ;
原始请求触发器:
- exports.handler = (event,callback) => {
- const request = event.Records[0].cf.request;
- const sessionHeaderName = 'X-Session-Cookies';
- let cookie = '';
- if (request.headers[sessionHeaderName.toLowerCase()]) {
- console.log(request.headers[sessionHeaderName.toLowerCase()]);
- cookie = request.headers[sessionHeaderName.toLowerCase()][0].value;
- }
- request.headers.cookie = [{ key : 'Cookie',value : cookie }];
- callback(null,request);
- };