[英]How to implement AntiForgery Token in Angular with NET 6
我正在處理幾個關於使用 angular 實現防偽令牌的過時文檔。 就我而言,我在沒有 MVC Razor 的情況下工作,只有 angular 13.3.4 和 NET 6.0
我只是進行配置:
builder.Services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
});
builder.Services.AddScoped<AntiforgeryMiddleware>();
然后是控制器:
public class AntiforgeryMiddleware : IMiddleware
{
private readonly IAntiforgery _antiforgery;
public AntiforgeryMiddleware(IAntiforgery antiforgery)
{
_antiforgery = antiforgery;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var isGetRequest = string.Equals("GET", context.Request.Method, StringComparison.OrdinalIgnoreCase);
if (!isGetRequest)
{
_antiforgery.ValidateRequestAsync(context).GetAwaiter().GetResult();
}
await next(context);
}
}
但仍然無法得到有角度的東西。 我的帖子是這個(只是為了測試它):
import { Component, Inject } from '@angular/core';
import { HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpXSRFInterceptor } from 'src/app/interceptors/tok.interceptor';
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpXSRFInterceptor, multi: true }
]
@Component({
selector: 'app-fetch-data',
templateUrl: './fetch-data.component.html'
})
export class FetchDataComponent {
public lenormandjack: LenormandHand = {} as LenormandHand;
constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string, ) {
http.post<LenormandHand>(baseUrl + 'api/lenormand', null, { withCredentials: true }).subscribe(result => {
this.lenormandjack = result;
console.dir(result);
console.log("OK");
console.dir(this.lenormandjack);
}, error => console.error(error));
}
}
我正在學習角度,我無法獲得甚至可以編譯為打字稿的代碼。 完全被阻止,並且多次(數十次)搜索中的文檔返回相同。 或者只是為了 WebApi。
我正在嘗試使用此控制器進行防偽工作:
[HttpPost]
[ValidateAntiForgeryToken]
public LenormandHand Post()
{
return foobar;
}
我的攔截器:
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpXsrfTokenExtractor } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable()
export class XsrfInterceptor implements HttpInterceptor {
constructor(private tokenExtractor: HttpXsrfTokenExtractor) { }
private actions: string[] = ["POST", "PUT", "DELETE"];
private forbiddenActions: string[] = ["HEAD", "OPTIONS"];
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token = this.tokenExtractor.getToken();
console.log ("TOKEN: "+token);
let permitted = this.findByActionName(request.method, this.actions);
let forbidden = this.findByActionName(request.method, this.forbiddenActions);;
if (permitted !== undefined && forbidden === undefined && token !== null) {
request = request.clone({ setHeaders: { "X-XSRF-TOKEN": token } });
}
return next.handle(request);
}
private findByActionName(name: string, actions: string[]): string | undefined {
return actions.find(action => action.toLocaleLowerCase() === name.toLocaleLowerCase());
}
}
任何幫助都會受到重視,評論,問題,答案,任何東西。 提前致謝
更新:
在此之后: 使用令牌 API 和 Angular 進行防偽我可以編譯,但答案是 400 bad request。 在深層,包含 X-XSRF-TOKEN 的標頭始終為 false
終於做到了。 有很多變化(而不是),但是為了安全地實現這一點,您必須考慮很多因素。
我將列舉並制作一個教程,因為我浪費了很多時間來解決這個請求/問題。
The question itself I made is fine, so you can the code for the answer from the question itself.
甚至不要嘗試“控制器方式”來生成令牌。 是無意義的,因為每個人都可以調用它。
調用應具有以下 cookie 選項:
Path = "/", HttpOnly = false, Secure = true, SameSite = SameSiteMode.Strict
設置只需要:
這個:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
和這個:
app.UseAntiforgeryToken();
我在這里使用“api”,因為我只想用“api”保護控制器,所以我可以選擇什么和不做什么。
constructor(http: HttpClient, @Inject('BASE_URL') baseUrl: string, ) {
http.post<yourclass>(baseUrl + 'api/controller', null, { withCredentials: true }).subscribe(result => {
this.yourinstance = result;
}, error => console.error(error));
}
}
app.module.ts
文件中添加這個:
import { XsrfInterceptor } from 'src/app/interceptors/tok.interceptor';
然后在@NgModule @NgModule({
部分:
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor, multi: true }
],
總共喜歡:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { CounterComponent } from './counter/counter.component';
import { FetchDataComponent } from './fetch-data/fetch-data.component';
import { XsrfInterceptor } from 'src/app/interceptors/tok.interceptor';
@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
HomeComponent,
CounterComponent,
FetchDataComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
HttpClientModule,
FormsModule,
RouterModule.forRoot([
{ path: '', component: HomeComponent, pathMatch: 'full' },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
])
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: XsrfInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
所以我的控制器有這個:
[ApiController]
[Route("api/[controller]")]
我的方法是這樣的:
[HttpPost]
[ValidateAntiForgeryToken]
public Method Post()
{
因此,您可以進行 Invoke 檢查路徑是否具有 api。 到處都有這個實現的幾個例子,因為它是針對 web api 的。 根據 gusto e piacere,這完全是可選的。
您將其添加到proxy.config.js
const PROXY_CONFIG = [
{
context: [
"/imgs",
"/api"
],
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.