Angular Client

נבנה דמו של פרוייקט אנגולרי כדי לראות איך מתמודדים עם האתגרים של הסרבר מול ה-client. אחר כך נייצר בקשה מהפרוייקט כדי להציג את רשימת המוצרים על המסך.

ניצור באנגולר קומפוננטה שתטען בעמוד הראשי והיא תלך להביא את המוצרים.

ng g c components/product-list

קובץ product-list.component.ts

export class ProductListComponent{
    products: Product[];
    constructor(private httpClient: HttpClient){}

    ngOnInit(){
        this.httpClient.get<Product[]>('https://localhost:3000/api/Products')
            .subscribe(products => {
        });
    }
}

קובץ product.model.ts

export interface Product{
    readonly id: number,
    readonly name: string,
    readonly description: string,
    readonly price: number,
    readonly amount: number,
    readonly producer: string
}

קובץ product-list.component.html

{{ products | json }}

נקרא לקומפוננטה מקובץ ה-app ונקבל שגיאה שקשורה ל-cors.

Cors Middleware

כשאנחנו מתחברים ל-app שיצרנו באנגולר, אנחנו נמצאים ב-post מספר 4200, שבוא שונה מה-post של ה-api. מבחינת הדפדפן זה דומיין שונה.

הדפדפן לא מאפשר לדומיין אחד לפנות לאחר בלי אישור. דומיין צריך לאשר איזה דומיינים יכולים לפנות אליו, עם איזה headers ועם איזה verbs הדומיין יכול להגיע (post, get, delete, put).

Options

הדפדפן מוציא בקשת options ל-api ורוצה לקבל ממנו מה הפעולות המותרות אצלו כמו שראינו בסעיף הקודם. פעולה כזאת מתאים להכניס ב-middleware של ה-api.

יש לנו middleware מובנה לפעולה הזאת ומפעילים אותו באמצעות UseCors.

קובץ program.cs

...
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

כמובן שלא מספיק להוסיף את UseCors כי עכשיו הדפדפן מחכה לתשובה. ההגדרה הזאת נמצאת בתוך ה-services. באיזור הזה נגדיר מה הצורה שבה רוצים לעבוד דרך AddCors. אנחנו נשתמש ב-action ונוסיף לו policy עם שם + קונפיגורציה של מה אני רוצה לאפשר.

קובץ program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.Configure<HeadersRemoveConfig>(builder.Configuration.GetSection("HeadersToRemove"));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddCors(Action => Action.AddPolicy("aspnet-course",
    config => config.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));

// Resolve DI
builder.Services.AddSingleton<IProductsRepository, ProductsRepository>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors("aspnet-course");
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

במקרה שלנו אנחנו אומרים שאפשר לפנות עם כל header, origin, method.

יש לנו פה חיבור בין השימוש ב-UseCors לשימוש ב-AddCors. אפשר להגדיר כמה policies בתוך ה-AddCors ולהחליט במה להשתמש עם תנאים וכו' בתוך ה-UseCors.

עכשיו אנחנו צריכים לקבל את הנתונים ב-app.