Angular 2:将 csrf 参数添加到 noNgForm
Posted
技术标签:
【中文标题】Angular 2:将 csrf 参数添加到 noNgForm【英文标题】:Angular 2: add csrf parameter to noNgForm 【发布时间】:2017-05-30 16:34:13 【问题描述】:今天遇到了从 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 忽略这一点并让您的浏览器执行帖子,您必须添加 ngNoForm
标头:
<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 保护不让我提交表单。我得到了例外:
在请求参数“_csrf”上发现无效的 CSRF 令牌“null” 或标题“X-CSRF-TOKEN”
那么,问题是如何为angular模板提供csrf的值?
【问题讨论】:
【参考方案1】:我发现了一个很好的例子,这是如何在 JHipster 框架中完成的。 需要三样东西:
-
angular2-cookie 插件
CSRFService
向表单添加隐藏参数
添加 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 的表单中添加 hidden 参数:
<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 2:将 csrf 参数添加到 noNgForm的主要内容,如果未能解决你的问题,请参考以下文章
使用 CSRF_COOKIE_HTTPONLY 将 Django CSRF 令牌传递给 Angular