当前位置: 首页 > 知识库问答 >
问题:

在角度6中添加Xsrf令牌时出现的问题

洪飞龙
2023-03-14

从通过API提交的表单中发布数据是成功的。

但是,在将X-CSRF-TOKEN添加到头并设置withCredentials:true之后,结果数据没有发布到名为insert的脚本中。php

错误:

加载失败http://localhost/simple_api/insert.php:对飞行前请求的响应未通过访问控制检查:当请求的凭据模式为“包括”时,响应中“访问控制允许来源”标头的值不得为通配符“*”。起源'http://localhost:4200因此,不允许访问。XMLHttpRequest启动的请求的凭据模式由withCredentials属性控制。

用凭据删除:成功发布了true结果数据。但是看不到X-CSRF-TOKEN

应用程序。单元ts

import { HttpModule } from '@angular/http';
import { AppRoutingModule } from './app-routing.module';
import {HttpClientModule, HttpClientXsrfModule} from "@angular/common/http";
import { UsrService } from './usr.service';
import { AppComponent } from './app.component';

@NgModule({
    declarations: [
      AppComponent,
      RegisterComponent,
      LoginComponent
    ],
    imports: [
      BrowserModule,
      FormsModule,
      HttpModule,
      AppRoutingModule,
      HttpClientModule,
      HttpClientXsrfModule.withOptions({
        cookieName: 'XSRF-TOKEN',
        headerName: 'X-CSRF-TOKEN'
      })
    ],
    providers: [UsrService],
    bootstrap: [AppComponent]
  })
  export class AppModule { }

使用者服务。ts

import { Http, Headers, RequestOptions, Response, URLSearchParams } from '@angular/http';
addUser(info){
    console.log(info);
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers, withCredentials: true });
    console.log(options);
    return this._http.post("http://localhost/simple_api/insert.php",info, options)
      .pipe(map(()=>""));
  }

insert.php

<?php
$data = json_decode(file_get_contents("php://input"));
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Headers: X-CSRF-Token, Origin, X-Requested-With, Content-Type, Accept");
?>

import {HttpClient, HttpClientModule, HttpClientXsrfModule} from "@angular/common/http";

constructor(private _http:HttpClient) { }

  addUser(info){
    console.log(info);
    // let headers = new Headers({ 'Content-Type': 'application/json' });
    // let options = new RequestOptions({ headers: headers, withCredentials: true });
    // console.log(options);
    return this._http.post("http://localhost/simple_api/insert.php",info)
        .subscribe(
                data => {
                    console.log("POST Request is successful ", data);
                },
                error => {
                    console.log("Error", error);
                }
            ); 
  }

应用程序。单元ts

import {HttpClientModule, HttpClientXsrfModule} from "@angular/common/http";

imports: [
    ...
    HttpClientModule,
    HttpClientXsrfModule.withOptions({
      cookieName: 'XSRF-TOKEN',
      headerName: 'X-CSRF-TOKEN'
    })
  ],
...

共有2个答案

东方宜
2023-03-14

服务器端,XSRF-TOKEN不是头,而是要事先设置的cookie。这个cookie应该从服务器发送到Angular应用程序所在的页面,即下面的示例中的模板“some”。样板html。twig'应加载Angular应用程序。

这样可以正确添加和发送正确的X-XSRF-etc标题。

请注意:cookie必须在生成时将HttpOnly选项设置为FALSE,否则Angular将看不到它。

例如,如果您使用Symfony,您可以在控制器操作中设置如下XSRF cookie:

namespace App\Controller;

use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
  /**
   * Disclaimer: all contents in Route(...) are example contents
   * @Route("some/route", name="my_route")
   * @param Request $request
   * @return \Symfony\Component\HttpFoundation\Response
   */
  public function someAction(Request $request, CsrfTokenManagerInterface $csrf)
  {
    $response = $this->render('some.template.html.twig');
    if(!$request->cookies->get('XSRF-TOKEN')){
      $xsrfCookie = new Cookie('XSRF-TOKEN',
        'A_Token_ID_of_your_Choice',
        time() + 3600, // expiration time 
        '/', // validity path of the cookie, relative to your server 
        null, // domain
        false, // secure: change it to true if you're on HTTPS
        false // httpOnly: Angular needs this to be false
      ); 
      $response->headers->setCookie($xsrfCookie);
    }

    return $response;
  }
}
陈欣荣
2023-03-14

将以下标题添加到php代码

header("Access-Control-Allow-Credentials: true");

另外,为什么要混合使用旧的HttpModule和新的HttpClient模块<代码>请求选项和标题在angular 6中不推荐使用

如果使用HttpClient,则默认情况下内容类型已设置为json,并且HttpClientXsrfModule已设置withCredentials

您的请求可以简化为

 return this._http.post("http://localhost/simple_api/insert.php",info);

编辑由HttpClientXsrfModule在幕后创建的默认拦截器似乎无法处理绝对URL。。。。

https://github.com/angular/angular/issues/18859

 类似资料:
  • 我已经添加了授权密钥,如下所示 我没有发现任何错误,但是在标题中没有找到授权 角6 从@angular/common/http使用的服务 URL在邮递员工作正常 我得到的错误如下 http.service.ts:84后端返回代码0,正文为:[对象Progress事件]正文为:{"标头":{"规范化名称":{},"lazyUpdate": null,"标头":{}},"状态": 0,"statusT

  • 用于初始化会话的Web API方法正在成功返回cookie。前端是angular的,所以我调用cookie XSRF-TOKEN,因为angular说它将接受该值,并在所有后续请求中将其转换为名为X-XSRF-TOKEN的头。 作为参考,创建cookie的WebAPI获取控制器方法如下 使用Fiddler,我可以在响应中看到cookie。现在我期待两件事 对同一域的所有后续API调用应在请求头中包

  • 我需要在基于url的懒惰模块中加载详细信息。所以,我使用了懒惰的辅助路由。但是,当我使用辅助路由时,我面临以下问题。 错误错误:未捕获(promise中):错误:无法匹配任何路线。URL段:“lazy/aux1”错误:无法匹配任何路由。URL段:ApplyRedirects.noMatchError处的“lazy/aux 1”(https://lazy-load-auxiliary-b7vpg-e

  • 我在重定向到访问令牌入口点/oauth/token时遇到问题,这将在下面详述。我希望有人能给我一些光,因为我花了很多时间来实现这一点。 另外,有趣的是,即使按照他们的说明,我也无法使用SoapUI 5.0社区版进行测试。它设置了授权代码,但稍后会失败,因为您需要将重定向URI设置为“urn:ietf:wg:oauth:2.0:oob”。 因为Spring-Security-Oauth2缺少很多好的

  • 我正在尝试构建一个应用程序,该应用程序使用Microsoft Graph自动创建和读取存储在SharePoint 365中的OneNotes中的页面。 只要我登录,我就可以使用 Graph 资源管理器成功执行此操作,但无法使用 Postman 中的持有者令牌使其工作 我得到的错误是:scp 或角色声明需要存在于令牌中 我成功地获得了一个访问令牌: 并传递grant_type、client_id、c

  • 如果访问令牌请求是有效的且被授权,授权服务器如5.1节所述颁发访问令牌以及可选的刷新令牌。如果请求因客户端身份验证失败或无效,授权服务器如5.2节所述的返回错误响应。 5.1. 成功响应 5.2. 错误响应