Angular 2:将csrf参数添加到noNgForm
Angular 2: add csrf parameter to noNgForm
今天在 angular SPA 上从 html 模板提交表单时遇到了问题。
首先,带有提交的简单表单无法开箱即用,因为 angular 捕获了不允许提交表单的提交事件。
<form action="/api/connect/facebook" method="POST">
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
要让 angular 忽略它并让您的浏览器执行 post 您必须添加 ngNoForm
header:
<form ngNoForm action="/api/connect/facebook" method="POST">
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
这对于 SPA 来说可能不是很常见,因为这样的表单提交将使浏览器远离 SPA,但这正是我所需要的。
好东西 - 我使用 spring-boot 作为我的后端,所以使用 spring-security 它有很好的 csrf 和 cors 保护,不允许我提交表单。我收到异常:
Invalid CSRF Token 'null' was found on the request parameter '_csrf'
or header 'X-CSRF-TOKEN'
所以,问题是如何为angular模板提供csrf的值?
我找到了一个很好的示例,说明如何在 JHipster 框架中完成此操作。
需要三件事:
- angular2-cookie 插件
- CSRF服务
- 向表单添加隐藏参数
添加angular2-cookie插件很简单:
npm install angular2-cookie --save
但是,您需要将所有必需的映射添加到 SystemJS 或您使用的任何模块框架。对于 SystemJS,一切都解释得很好 here。仔细阅读,因为我第一次忘记制作:
import { CookieService } from 'angular2-cookie/services/cookies.service';
@NgModule({
providers: [ CookieService ],
})
export class AppModule { }
现在,CSRFService:
import { Injectable } from '@angular/core';
import { CookieService } from 'angular2-cookie/core';
@Injectable()
export class CSRFService {
constructor(private cookieService: CookieService) {}
getCSRF(name?: string) {
name = `${name ? name : 'XSRF-TOKEN'}`;
return this.cookieService.get(name);
}
}
现在,您需要将它注入呈现模板的组件:
import {Component, OnInit} from '@angular/core';
import {CSRFService} from './csrf.service';
@Component({
moduleId: module.id,
selector: 'login-form',
templateUrl: 'login.component.html',
styleUrls: ['login.component.css']
})
export class LoginComponent implements OnInit {
private csrf: string;
constructor(private csrfService: CSRFService) { }
ngOnInit() {
this.csrf = this.csrfService.getCSRF();
}
}
最后不要忘记在 login.component.html 中的表单中添加隐藏参数:
<form ngNoForm action="/api/connect/facebook" method="POST">
<input name="_csrf" type="hidden" value="{{ csrf }}"/>
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
希望,这对任何人都有帮助,因为我花了半天时间试图弄清楚如何实现我想要的。
今天在 angular SPA 上从 html 模板提交表单时遇到了问题。 首先,带有提交的简单表单无法开箱即用,因为 angular 捕获了不允许提交表单的提交事件。
<form action="/api/connect/facebook" method="POST">
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
要让 angular 忽略它并让您的浏览器执行 post 您必须添加 ngNoForm
header:
<form ngNoForm action="/api/connect/facebook" method="POST">
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
这对于 SPA 来说可能不是很常见,因为这样的表单提交将使浏览器远离 SPA,但这正是我所需要的。
好东西 - 我使用 spring-boot 作为我的后端,所以使用 spring-security 它有很好的 csrf 和 cors 保护,不允许我提交表单。我收到异常:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'
所以,问题是如何为angular模板提供csrf的值?
我找到了一个很好的示例,说明如何在 JHipster 框架中完成此操作。 需要三件事:
- angular2-cookie 插件
- CSRF服务
- 向表单添加隐藏参数
添加angular2-cookie插件很简单:
npm install angular2-cookie --save
但是,您需要将所有必需的映射添加到 SystemJS 或您使用的任何模块框架。对于 SystemJS,一切都解释得很好 here。仔细阅读,因为我第一次忘记制作:
import { CookieService } from 'angular2-cookie/services/cookies.service';
@NgModule({
providers: [ CookieService ],
})
export class AppModule { }
现在,CSRFService:
import { Injectable } from '@angular/core';
import { CookieService } from 'angular2-cookie/core';
@Injectable()
export class CSRFService {
constructor(private cookieService: CookieService) {}
getCSRF(name?: string) {
name = `${name ? name : 'XSRF-TOKEN'}`;
return this.cookieService.get(name);
}
}
现在,您需要将它注入呈现模板的组件:
import {Component, OnInit} from '@angular/core';
import {CSRFService} from './csrf.service';
@Component({
moduleId: module.id,
selector: 'login-form',
templateUrl: 'login.component.html',
styleUrls: ['login.component.css']
})
export class LoginComponent implements OnInit {
private csrf: string;
constructor(private csrfService: CSRFService) { }
ngOnInit() {
this.csrf = this.csrfService.getCSRF();
}
}
最后不要忘记在 login.component.html 中的表单中添加隐藏参数:
<form ngNoForm action="/api/connect/facebook" method="POST">
<input name="_csrf" type="hidden" value="{{ csrf }}"/>
<input type="hidden" name="scope" value="email" />
<button type="submit" class="btn btn-primary btn-block"><i class="icon-facebook"></i> Login via Facebook</button>
</form>
希望,这对任何人都有帮助,因为我花了半天时间试图弄清楚如何实现我想要的。