0

I have a very simple local setup in which I'm trying to set a cookie and see it passed back to the server on subsequent calls.

I have an isolated C# 7.0 Azure Function as follows:

[Function("A")]
public HttpResponseData A([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "a")] HttpRequestData req)
{
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Access-Control-Allow-Origin", "http://cloudboy.local:7139");

    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
    response.WriteString("A");
    var cookie = new HttpCookie("CM_AUTH", "helloworld")
    {
        Expires = DateTimeOffset.UtcNow.AddDays(1),
        Domain = req.Url.Host,
        Path = "/",
    };
    response.Cookies.Append(cookie);

    return response;
}

[Function("B")]
public HttpResponseData B([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "b")] HttpRequestData req)
{
    var response = req.CreateResponse(HttpStatusCode.OK);
    response.Headers.Add("Access-Control-Allow-Origin", "http://cloudboy.local:7139");
    response.Headers.Add("Content-Type", "text/plain; charset=utf-8");

    response.WriteString("B");
    return response;
}

I have a very simple Angular application as well with one standalone component:

import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { take } from 'rxjs';

@Component({
  selector: 'cb-root',
  standalone: true,
  imports: [CommonModule, HttpClientModule],
  template: `
    <p>{{apiString}}</p>
    <button type="button" (click)="callB()">Call B</button>
  `,
  styles: [],
})
export class AppComponent implements OnInit {
  apiString = '';

  constructor(private http: HttpClient) {}

  ngOnInit(): void {
    this.http.get('http://apis.cloudboy.local:7138/api/a', { responseType: 'text' }).pipe(take(1)).subscribe(r => this.apiString = r);
  }

  callB(): void {
    this.http.get('http://apis.cloudboy.local:7138/api/b', { responseType: 'text' }).pipe(take(1)).subscribe(r => this.apiString = r);
  }
}

I've updated my hosts file to include the following entries:

127.0.0.1 cloudboy.local
127.0.0.1 apis.cloudboy.local

And updated my angular.json file so that the serve section looks as follows:

    "serve": {
      "builder": "@angular-devkit/build-angular:dev-server",
      "configurations": {
        "production": {
          "browserTarget": "cloudboy:build:production"
        },
        "development": {
          "browserTarget": "cloudboy:build:development",
          "host": "cloudboy.local",
          "port": 7139
        }
      },
      "defaultConfiguration": "development"
    },

When I launch both applications and go to http://cloudboy.local:7139/, the webpage loads and makes a call to the 'a' endpoint. I see the Set-Cookie header in the response as I would expect.

enter image description here

But when I look at the Application tab in my brower's dev tools, I don't see any cookies on my domain and when I click the button, the application makes the call to the 'b' endpoint and doesn't have the cookie on it.

I've tried quite a number of things including having both domains listen on port 80, removing domain/path, etc just to let things be default. I've tried hardcoding the domain to values like "cloudboy.local", ".cloudboy.local", "apis.cloudboy.local", ".apis.cloudboy.local", etc, etc. I've tried adding additional headers like "Access-Control-Allow-Headers" and "Access-Control-Expose-Headers". I've looked at many StackOverflow questions/answers(1, 2, 3) as well as some MDN articles(1, 2) without any luck.

How can I get the Azure Function to not only return a cookie, but then have it set as a header on subsequent requests to my domain?

peinearydevelopment
  • 11,042
  • 5
  • 48
  • 76

0 Answers0