Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Angular İle Token Authentication Uygulanan Web API Tetikleme

Merhaba,

Bir önceki Angular İle Web API Tetikleme başlıklı makalemde Angular uygulamalarında Web Apilerin nasıl tetiklendiğini incelemiştik lakin eğer kullanılacak web apinin token authentication ile güvenliği sağlanmışsa nasıl bir çalışma yapılması gerektiğini göz ardı etmiştik. İşte bu içeriğimizde Angular uygulamalarında token authentication ile güvenlik önlemi alınan web apilerin nasıl tetikleneceğini inceliyor olacağız.

Yazımıza başlamadan önce yukarıda adresini vermiş olduğum bir önceki makalenin içeriğinin bir devamı niteliğinde seyredeceğimizi bilmenizi isterim…

İlk olarak oluşturduğumuz Web Apiyi Token Authentication ile güvenlik kontrolünden geçirelim.(token authentication makalesini inceleyiniz.)

    [Authorize]
    public class PersonelController : ApiController
    {
        NorthwindEntities db = new NorthwindEntities();
        public IEnumerable<Personel> GetAll() => db.Personeller.Select(p => new Personel
        {
            PersonelID = p.PersonelID,
            Adi = p.Adi,
            SoyAdi = p.SoyAdi,
            Unvan = p.Unvan
        }).ToList();
        public Personel GetSingle(int id) => db.Personeller.FirstOrDefault(p => p.PersonelID == id);
        public IHttpActionResult PostAdd(Personel p)
        {
            if (p != null)
            {
                db.Personeller.Add(p);
                db.SaveChanges();
                return Ok(p);
            }
            return Ok("Personel ekleme başarısız.");
        }
        public IHttpActionResult PutUpdate(Personel p)
        {
            if (p != null)
            {
                Personeller updatePersonel = db.Personeller.FirstOrDefault(u => u.PersonelID == p.PersonelID);
                updatePersonel.Adi = p.Adi;
                updatePersonel.SoyAdi = p.SoyAdi;
                updatePersonel.Unvan = p.Unvan;
                db.SaveChanges();
                return Ok(updatePersonel);
            }
            return Ok("Personel güncelleştirme başarısız.");
        }
        [HttpDelete]
        public IHttpActionResult Remove(int id)
        {
            Personeller deletePersonel = db.Personeller.FirstOrDefault(p => p.PersonelID == id);
            db.Personeller.Remove(deletePersonel);
            db.SaveChanges();
            return Ok($"\"{deletePersonel.Adi} {deletePersonel.SoyAdi}\" isimli personel başarıyla silinmiştir.");
        }
    }

Bu şekilde web apideki tüm metotlara erişilebilmesi için token doğrulaması mecburiyetini getirmiş olduk.

Ardından Angular uygulamamızda Token doğrulaması neticesinde gelecek olan verileri karşılayacak nesnemizi oluşturalım.

export class Token {
    access_token: string;
    token_type: string;
    expires_in: number;
}

Akabinde Token doğrulaması için post edeceğimiz veriyi temsil edecek nesneyide oluşturalım.

export class PostToken {
    username: string;
    password: string;
    grant_type: string;
}

Bu verilerin neler olduğuna dair kaynağı belirtilen adresteki içerikte detaylı açıklamalarda bulunmuştuk.

Şimdi ise token doğrulmasını tetikleyecek olan servisimizi oluşturalım. Ben bu servise “AuthService” ismini yakıştırıyorum.

import { Injectable, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { PostToken } from '../classes/posttoken';
import { Token } from '@angular/compiler';


@Injectable()
export class AuthService {

  constructor(private httpClient: HttpClient, @Inject("url") private url: string) { }

  GetToken(postToken: PostToken) {
    let data = "username=" + postToken.username + "&password=" + postToken.password + "&grant_type=" + postToken.grant_type;
    let headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
    return this.httpClient.post(this.url + "token", data, { headers: headers });
  }
}

Burada dikkat edilmesi gereken husus, token için post edilecek datanın yukarıdaki formatta parse edilmiş olması gerekmektedir. Ayrıca “HttpHeaders” nesnesi ile yapacağımız post işleminin “Content-Type” özelliğini “application/x-www-form-urlencoded” şeklinde belirtmemiz gerekmektedir. Gerisi bu değişken ve nesneleri post fonksiyonunda ilgili alanlara belirtmektir.

Hatırlarsanız bir önceki yazımızda “PersonelComponent” isminde bir componentimiz vardı. Register işlemleri için bu componentimize aşağıdaki gibi ilgili fonksiyonu ekliyorum. Dolayısıyla elde edilen tokenı “HttpHeaders” tipinden bir global değişkene atıyorum ve tüm metotlarımda bu “HttpHeaders” nesnesini kullanarak alınan token ile gerekli işlemleri gerçekleştiriyorum.

import { Component, OnInit } from '@angular/core';
import { Personel } from '../../classes/personel';
import { PersonelService } from '../../services/personel.service';
import { AuthService } from '../../services/auth.service';
import { PostToken } from '../../classes/posttoken';
import { Token } from '../../classes/token';
import { HttpHeaders } from '@angular/common/http';

@Component({
  selector: 'app-personel',
  templateUrl: './personel.component.html',
  styleUrls: ['./personel.component.css']
})
export class PersonelComponent implements OnInit {
  personelList: Personel[];
  personel: Personel;
  constructor(private personelService: PersonelService, private authService: AuthService) { }
  headers: HttpHeaders;

  ngOnInit() {
  }
  Register(username: HTMLInputElement, password: HTMLInputElement) {
    let postToken: PostToken = {
      username: username.value,
      password: password.value,
      grant_type: "password"
    };
    this.authService.GetToken(postToken).subscribe((response: Token) => {
      this.headers = new HttpHeaders({ 'Authorization': 'Bearer ' + response.access_token });
    });
  }

  GetAll() {
    this.personelService.GetAll(this.headers).subscribe((response: Personel[]) => this.personelList = response);
  }
  GetSingle(id: number) {
    this.personelService.GetSingle(id, this.headers).subscribe((response: Personel) => this.personel = response);
  }
  PostAdd(adi: HTMLInputElement, soyAdi: HTMLInputElement, unvan: HTMLInputElement) {
    let postPersonel: Personel = {
      Adi: adi.value,
      SoyAdi: soyAdi.value,
      Unvan: unvan.value
    };

    this.personelService.PostAdd(postPersonel, this.headers).subscribe((response: Personel) => {
      if (response) {
        this.personelList.unshift(response);
        this.personel = response;
      }
    });
  }
  PutUpdate(id: HTMLInputElement, adi: HTMLInputElement, soyAdi: HTMLInputElement, unvan: HTMLInputElement) {
    let updatePersonel: Personel = {
      PersonelID: Number(id.value),
      Adi: adi.value,
      SoyAdi: soyAdi.value,
      Unvan: unvan.value
    };
    this.personelService.PutUpdate(updatePersonel, this.headers).subscribe((response: Personel) => {
      if (response) {
        this.GetAll();
        this.personel = response;
      }
    });
  }
  Remove(id: number) {
    this.personelService.Remove(id, this.headers).subscribe(response => {
      alert(response);
      this.GetAll();
    });
  }
}

Tabi “PersonelService” isimli servis içerisindeki fonksiyonlarımı buradaki imzalara uygun bir hale ve işlevselliğe getiriyorum.

import { Injectable, Inject } from '@angular/core';
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { inject } from '@angular/core/src/render3';
import { Personel } from '../classes/personel';

@Injectable()
export class PersonelService {

  constructor(private httpClient: HttpClient, @Inject("url") private url: string) { }

  GetAll(headers: HttpHeaders) {
    return this.httpClient.get(this.url + "api/personel/getall", { headers: headers });
  }
  GetSingle(id: number, headers: HttpHeaders) {
    return this.httpClient.get(this.url + "api/personel/getsingle/" + id, { headers: headers });
  }
  PostAdd(personel: Personel, headers: HttpHeaders) {
    return this.httpClient.post(this.url + "api/personel/postadd", personel, { headers: headers });
  }
  PutUpdate(personel: Personel, headers: HttpHeaders) {
    return this.httpClient.put(this.url + "api/personel/putupdate", personel, { headers: headers });
  }
  Remove(id: number, headers: HttpHeaders) {
    return this.httpClient.delete(this.url + "api/personel/remove/" + id, { headers: headers });
  }
}

İşte bitti…

Şimdi projeyi kaydedip, çalıştırma zamanı…

Hadi bakalım…
Angular İle Token Authentication Uygulanan Web API Tetikleme
Hooppbala!
“Ulan tam çalışacak diye hevesleniyorduk, hevesimiz kursağımızda kaldı…”

Ne ile karşılaştık?

Failed to load http://localhost:50875/api/personel/getall: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:4200’ is therefore not allowed access. The response had HTTP status code 400.

ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: “Unknown Error”, url: null, ok: false, …}

zone.js:2969 Cross-Origin Read Blocking (CORB) blocked cross-origin response http://localhost:50875/api/personel/getall with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

hatalarıyla…

Sakin olun. Bu hatalar farklı domainlerin birbirleriyle etkileşim sürecine girdiklerinde süreci daha da sağlıklı kontrol edebilmek için güvenlik amaçlı alınmış önlemlerden kaynaklanmaktadır. Bu hatalardan kurtulmak için ilgili Web API sınıfının başına aşağıdaki attribute’u olduğu gibi eklemeniz yeterli olacaktır.

[EnableCors(origins: "*", headers: "*", methods: "*")]
    [Authorize]
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class PersonelController : ApiController
    {
        .
        .
        .
    }

Bu ayarlamadan sonra projemizi kaydedip, yayınladığımızda artık sağlıklı bir şekilde çalıştığını göreceksiniz.
Angular İle Token Authentication Uygulanan Web API Tetikleme

Bu uzun ve zahmetli makaleden sonra artık Angular uygulamalarında Token Authentication uygulanmış Web API’ler üzerinde çalışmalarınızı gerçekleştirebileceksiniz.

Faydalı bir içerik olmasını umut ediyorum.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*