首页 文章

Angular 2:将csrf参数添加到noNgForm

提问于
浏览
0

今天在角度SPA上从html模板提交表单时遇到了问题 . 首先,提交的简单表单无法开箱即用,因为angular会 grab 提交事件而不让表单提交 .

<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> &nbsp;&nbsp;&nbsp;Login via Facebook</button>
   </form>

要让angular忽略它并让你的浏览器发布帖子,你必须添加 ngNoForm Headers :

<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> &nbsp;&nbsp;&nbsp;Login via Facebook</button>
   </form>

对于SPA来说这可能不是很常见,因为这样的表单提交会导致浏览器远离SPA,但这就是我需要的 .

好东西 - 我使用spring-boot作为我的后端,所以使用spring-security它有很好的csrf和cors保护,不让我提交表单 . 我得到了例外:

在请求参数'_csrf'或 Headers 'X-CSRF-TOKEN'上找到无效的CSRF令牌'null'

那么,问题是如何为角模板提供csrf的值?

1 回答

  • 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中将隐藏参数添加到表单中:

    <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> &nbsp;&nbsp;&nbsp;Login via Facebook</button>
    </form>
    

    希望,这对任何人都有帮助,因为我花了一半的时间试图弄清楚如何实现我想要的 .

相关问题