我正在使用Angular 8,与旧版后端(ASP.NET MVC 5 Framework)非CORE。 我试图发送网站的cookie,以便来自Angular网站的请求被视为已认证。
我创建了一个拦截器用于此操作。
import { HttpInterceptor, HttpHandler, HttpEvent, HttpRequest }
from '@angular/common/http';
import { Observable } from 'rxjs';
import { Injectable } from '@angular/core';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor() { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const newRequest = request.clone({
withCredentials: true,
});
return next.handle(newRequest);
}
}
这里是请求的代码
private getDefaultConfiguration(): configurationsType {
return {
observe: 'response',
responseType: 'json',
headers: new HttpHeaders().set('Content-Type', 'application/json')
};
}
public async get(endpoint: string, params: HttpParams = undefined) {
const options = this.getDefaultConfiguration();
if (params !== undefined)
options.params = params;
const response: HttpResponse<object> = await this.http.get(endpoint, options).toPromise();
return await this.errorCheck(response);
}
我可以确认拦截器通过console.log
语句正在执行。问题在于,我没有收到请求中的cookies(顺便说一下,是Http Get而不是Post),因此我的请求被视为未经身份验证。
我正在使用以下CORS问题过滤器:
public class AllowCrossSiteAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.RequestContext.HttpContext.Response;
response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
response.AddHeader("Access-Control-Allow-Headers", "*");
response.AddHeader("Access-Control-Allow-Methods", "*");
response.AddHeader("Access-Control-Allow-Credentials", "true");
base.OnActionExecuting(filterContext);
}
}
我全局注册过滤器,
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new AllowCrossSiteAttribute());
}
}
这是我期望在标头中发送的 cookie,这段代码来自登录方法
var ticket = new FormsAuthenticationTicket(SessionHelper.DefaultSession().KullaniciAdi, model.RememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted)
{
Expires = DateTime.Now.AddMinutes(timeout),
HttpOnly = true // cookie not available in javascript.
};
Response.Cookies.Add(cookie);
return RedirectToAction("Index", "Home");
这是Chrome中的Cookie
更新
我查看了这篇文章并将
set-cookie
的same-site
属性应用于none
,但仍未解决问题。我更新了
[AllowCrossSiteAttribute]
,因为我在Angular中遇到了另一个完全不同的问题。
public class AllowCrossSiteAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.RequestContext.HttpContext.Response;
response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
response.AddHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
response.AddHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.AddHeader("Access-Control-Allow-Credentials", "true");
base.OnActionExecuting(filterContext);
}
}
same-site
属性设置为none
是至关重要的,但这还不够,我还需要添加最后一步才能让魔法发生:从headers: new HttpHeaders().set('Content-Type', 'application/json')
中删除.set('Content-Type', 'application/json')
。 - Hakan FıstıkHttpCookie#SameSite
属性设置为SameSite.None
来设置same-site
属性的吗?你能确认只是在Angular端移除'Content-Type', 'application/json'
头部就解决了问题吗?了解这种情况可能的原因会很有意思。你可以提供一个最小化的MVC应用程序设置,以重现这个问题吗?我很有兴趣详细地研究一下。 - Jota.Toledo