XSRF-如何设置跨域Cookie [英] XSRF - how to set cross-origin cookie
问题描述
我已经开发了REST API和两个JavaScript客户端(单页应用和本地应用-基于电子).在这两个客户端中,我的用户都通过OAuth2流进行身份验证:
I have developed REST API, and two JavaScript clients (Single Page App & native app - based on electron). In both clients my users are authenticating via OAuth2 flow:
- 将用户密码发送到服务器
- 获取access_token(以纯文本格式)和refresh_token(以httponly cookie格式)
- 当令牌过期时,他们正在刷新它,将请求发送到/refresh端点(服务器从cookie中读取refresh_token)
现在,我想实现csrf保护.所以我在后端(Spring)上实现了它:
Now I would like to implement csrf protection. So I implemented it on my back-end side (Spring):
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()).and()
.authorizeRequests().antMatchers("/", "/index.html", "/token/**").permitAll()
.anyRequest().authenticated();
}
我的SPA正常工作,角度从cookie读取XSRF-TOKEN并将其发送到X-XSRF-TOKEN标头中.电子应用程序出现问题.它无权访问Cookie(由于来源不同-电子在file://
网址上运行),因此无法设置X-XSRF-TOKEN标头.
My SPA works perfectly, angular reads XSRF-TOKEN from cookie and sends it in X-XSRF-TOKEN header. I got problem with electron app. It doesn't have access to cookie (because of different origin - electron is running on file://
url), so it is unable to set X-XSRF-TOKEN header.
我该如何处理此类问题?有什么方法可以使跨域" cookie无效?还是我可以通过电子魔术电子API以某种方式更改cookie的值(如果它可以访问文件系统,也许可以访问在计算机上创建的任何cookie)?
How can I deal with such problem? Is there any way to instatiate "cross-origin" cookie? Or maybe I can somehow takie the cookie value via electron magic electron API (if it has access to file-system, maybe it have access to any cookie which is created on the machine)?
推荐答案
我遇到了同样的问题,最终设法通过实现如下角度的http拦截器来解决了这个问题:
I had the same problem and eventually managed to fix it by implementing an angular http interceptor like this:
@Injectable()
export class HttpXsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor, //from angular
private nativeAuthService: NativeAuthService) { //my native service
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
//this works in web
const headerName = 'X-XSRF-TOKEN';
const token = this.tokenExtractor.getToken() as string;
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, token) });
return next.handle(req);
}
//this works in electron
return this.nativeAuthService.getCookieValue('XSRF-TOKEN').pipe(
mergeMap((xsrfToken: string) => {
if (xsrfToken && !req.headers.has(headerName)) {
req = req.clone({ headers: req.headers.set(headerName, xsrfToken) });
}
return next.handle(req);
}),
);
}
}
我的nativeAuthService基本上只是在电子主过程中调用此方法:
And my nativeAuthService basically just calls this method in the electron main process:
export function getCookieValue(cookieName: string): Observable<string> {
return from(session.defaultSession.cookies.get({ name: cookieName })
.then((cookies: Electron.Cookie[]) => {
if (cookies.length == 1) {
return cookies[0].value;
} else {
if (cookies.length > 1) {
throw Error(`There is more than one cookie with the name: ${ cookieName }.`);
}
return '';
}
}));
}
这篇关于XSRF-如何设置跨域Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!