I inherited an ASP.NET MVC3 app using forms authentication with sessionID and ASPXAUTH in cookies. Now I am trying to replace the Razor view frontend with an Angular 2 app.
I have setup Angular to call the backend once upon first page load to obtain a sessionID from ASP.NET (ngOnInit in auth component). The sessionID is returned as a JSON response. I have made sure to add some "dummy data" to the session to avoid it being re-generated by default for "not being used" in the backend. I then set this sessionID inside a cookie at the frontend using the "ng2-cookie" library.
This works fine, but the sessionID on the backend keeps changing for every request I make. There must be something wrong at the "Angular end", since the sessionID won't change if I manually visit the backend API endpoint (/Api/Account/Login) in the browser.
My gut is telling me that Angular is not passing the cookie to the backend.
I have read about withCredentials
in Angular 1, but can't find the corresponding solution for Angular 2.
- Is the purpose of withCredentials to forward cookie data to the API/target?
- Can withCredentials be implemented in Angular 2?
- If withCredentials is not an option, how do I pass the cookie along to the backend?
Update: Still re-generates sessions
I have followed the instructions for RC1 but it still won't work.
I created CustomBrowserXhr.ts
and added the following code to it:
import { Injectable } from '@angular/core';
import { BrowserXhr } from '@angular/http';
@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
constructor() {}
build(): any {
let xhr = super.build();
xhr.withCredentials = true;
return <any>(xhr);
}
}
In my main.ts
where I bootstrap the application:
import { bootstrap } from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS, Http, BrowserXhr } from '@angular/http';
import { TRANSLATE_PROVIDERS, TranslateService, TranslatePipe, TranslateLoader, TranslateStaticLoader } from 'ng2-translate/ng2-translate';
import { provide, enableProdMode } from '@angular/core';
import { LoggerService } from './services/LoggerService';
import { CustomBrowserXhr } from './helpers/CustomBrowserXhr'; // Not needed after RC2
// Enable production mode
enableProdMode();
// Import our main angular component
import { AppComponent } from './components/app/app.component';
// Bootstrap it to angular
bootstrap(AppComponent, [
HTTP_PROVIDERS,
provide(BrowserXhr, { useClass: CustomBrowserXhr }),
provide(TranslateLoader, {
useFactory: (http: Http) => new TranslateStaticLoader(http, 'app/languages', '.json'),
deps: [Http]
}),
TranslateService,
LoggerService
]);
My AuthService
makes the call like this:
getSession() {
return this._http.get(appSettings.apiUrl + 'Account/Login', {headers: this.headers})
.map((response: Response) => response.json())
.do(data => console.log(data))
.catch(this.handleError);
}
And in my backend, the request is handeled like this:
[HttpGet]
public ActionResult Login()
{
#if DEBUG
// Just for development: Angular calls from ":3000" to .NET = fails origin check
Response.AppendHeader("Access-Control-Allow-Origin", "*");
#endif
// Grab session for the calling user
this._sessionID = System.Web.HttpContext.Current.Session.SessionID;
// Assign something to the session to avoid it being re-generated on EVERY request
// https://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx
System.Web.HttpContext.Current.Session["api"] = 1;
// Setup JSON feedback
var feedback = new
{
success = true,
session = this._sessionID
};
return Json(feedback, JsonRequestBehavior.AllowGet);
}
This returns a sessionID in JSON and as "Set-Cookie" in the headers. They are equal to each other.
But on the next request, I get a brand new sessionID again.