Search code examples
google-cloud-platformgoogle-cloud-cdn

Google Cloud CDN signed cookies with bucket as backend


As an alternative to signed urls with a url prefix, I'm trying to get signed cookies working. Google Cloud CDN is setup with a backend bucket which is configured and working for standard signed urls.

Using these Go examples I've implemented a cookie signing function in nodejs(typescript) that when provied with the test sample data produces the expected outcome.

export function signCookie(urlPrefix: any, keyName: string, key: any, experation: Date): string {
    // Base64url encode the url prefix
    const urlPrefixEncoded = Buffer.from(urlPrefix)
        .toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_');

    // Input to be signed
    const input = `URLPrefix=${urlPrefixEncoded}:Expires=${experation.getTime()}:KeyName=${keyName}`;

    // Create bytes from given key string.
    const keyBytes = Buffer.from(key, 'base64');

    // Use key bytes and crypto.createHmac to produce a base64 encoded signature which is then escaped to be base64url encoded.
    const signature = createHmac('sha1', keyBytes)
        .update(input)
        .digest('base64').replace(/\+/g, '-')
        .replace(/\//g, '_');

    // Adding the signature on the end if the cookie value
    const signedValue = `${input}:Signature=${signature}`;

    return signedValue;
}

When I then use the same function to produce signed cookie values for my actual cdn instance I get the following (key name and url prefix not actual):

URLPrefix=aHR0cHM6L------------------HdhcmUuaW8v:Expires=1587585646437:KeyName=my-key-name:Signature=2mJbbtYVclycXBGIpKzsJWuLXEA=

Creating a cooking using firefox dev tools I get the following two results when the cookie is attached and when it is not:

Signed Cookie attached Without signed cookie

It appears that the cookie "Cloud-CDN-Cookie" is just being passed through Cloud CDN and straight to the backend bucket where it's ignored and the standard response access denied response is given.

The cloud platform logs shows no cdn intervention.

With cookie attached with cookie attached No cookie attached without cookie attached

Is there something in either the signing implementation or creation and use of the cookie that I'm doing wrong?


Solution

  • My Google project did not yet have the signed cookie feature enabled. Another user contacted support and once the issue was resolved for them it was resolved for me no change to code and it works.

    This is my final nodejs(typescript) signed cookie implementation.

    function signCookie(urlPrefix: any, keyName: string, key: any, experation: Date): string {
        // Base64url encode the url prefix
        const urlPrefixEncoded = Buffer.from(urlPrefix)
            .toString('base64')
            .replace(/\+/g, '-')
            .replace(/\//g, '_');
    
        // Input to be signed
        const input = `URLPrefix=${urlPrefixEncoded}:Expires=${experation.getTime()}:KeyName=${keyName}`;
    
        // Create bytes from given key string.
        const keyBytes = Buffer.from(key, 'base64');
    
        // Use key bytes and crypto.createHmac to produce a base64 encoded signature which is then escaped to be base64url encoded.
        const signature = createHmac('sha1', keyBytes)
            .update(input)
            .digest('base64').replace(/\+/g, '-')
            .replace(/\//g, '_');
    
        // Adding the signature on the end if the cookie value
        const signedValue = `${input}:Signature=${signature}`;
    
        return signedValue;
    }