每个请求都填充一个WithCredentialsInterceptor
:
@Injectable()
export class WithCredentialsInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
withCredentials: true
});
return next.handle(request);
}
}
在后面:
CORS
中间件:
// process.env.CLIENT = https://www.example.com
this.router.options('*', cors({origin: process.env.CLIENT, credentials: true}));
this.router.use(cors({origin: process.env.CLIENT, credentials: true}));
// On valid Login:
res.cookie('SESSIONID', createdSession, {maxAge: someTime, httpOnly: true, secure: true});
res.cookie('XSRF-TOKEN', createdToken, {maxAge: someTime});
开发中: ng serve --ssl
使用proxy.conf.json
而非NOT cors
-两个cookie均已成功设置在可见的“ cookie jar”(devtools->应用程序/存储-> Cookies)中。
删除proxy.conf.json
以支持CORS模仿生产体系结构仅设置XSRF cookie,但标记为SESSIONID
和secure
的{{1}}则不是。在这种情况下发送的标头仅为httpOnly
(我认为这是伪造X-XSRF-TOKEN
开发服务器的预期行为)。
假设它可以在合法的HTTPS环境中正常运行,我继续进行结构设计。
域名如下:
问题
“ Cookie jar”中均未设置两个Cookie。
替代: 成功登录后,cookies将显示在响应标题中:
响应标题:
HTTPS
它们也在下一个请求中发送:
请求标头
set-cookie: XSRF-TOKEN=The-legit-XSRF-TOKEN; Max-Age=number; Path=/; Expires=Tue, 22 Oct 2019 18:56:31 GMT
set-cookie: SESSIONID=The-legit-SessionID-Token; Max-Age=number; Path=/; Expires=Tue, 22 Oct 2019 18:56:31 GMT; HttpOnly; Secure
但是cookie: SESSIONID=The-legit-SessionID-Token; XSRF-TOKEN=The-legit-XSRF-TOKEN
不会捕获应有的cookie,也无法通过XSRFInterceptor
来获取cookie,因此请求不会与document.cookie
一起发送。
X-XSRF-TOKEN
实现:
XSRFInterceptor
在我的服务器日志中,我收到确认cookie良好的确认,但是由于@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Obse rvable<HttpEvent<any>> {
const HEADER_NAME = 'X-XSRF-TOKEN';
// let TOKEN = document.cookie.split('; ').find(cookie => cookie.startsWith('XSRF-TOKEN'));
let TOKEN = this.tokenExtractor.getToken() as string;
if (TOKEN && !req.headers.has(HEADER_NAME)) {
// TOKEN = TOKEN.split('=')[1];
req = req.clone({ headers: req.headers.append(HEADER_NAME, TOKEN) });
}
console.log(req) // <-- withCredentials: true
return next.handle(req);
}
}
提取令牌失败,中间件拒绝了我的请求:
XSRFInterceptor
我设法通过将合法的console.log(csrfCookie, csrfHeader); // The-legit-XSRF-TOKEN, undefined
console.log(csrfCookie === csrfHeader); // false
和SESSIONID
复制到cookie罐中进行登录,并尝试注销时-我注意到Angular也忽略了服务器发送的XSRF-TOKEN
标头,因为我已按正常方式转移到登录页面,但是复制的Cookie并未删除。
有人认识到这个问题吗?
答案 0 :(得分:0)
已解决,
在res.cookie
中,我添加了domain: '.example.com'
。
没有任何域规范,在开发环境中默认为localhost
,两端相同。但是在生产中,我猜它默认为api.example.com
,并且由于它与原始网址www.example.com
不匹配,因此浏览器没有将其视为必须放在jar中的内容。