# - 8.web API
# - 8.web API
API]
İÇİNDEKİLER
SOA
NEDİR?
(Service
Oriented
Architecture)
............................................................................................
2
SOA’NIN
FAYDALARI
.......................................................................................................................................................
2
API
NEDİR?
(Application
Programming
Interface)
..................................................................................
2
WEB
SERVICE
NEDİR?
.........................................................................................................................................
3
RESTFUL
SERVICE
NEDİR?
................................................................................................................................
3
[Link]
WEB
API
.................................................................................................................................................
3
WEB
API
ÖZELLİKLERİ
...................................................................................................................................................
3
Web
API
Tercih
Etmemizin
Sebepleri
.......................................................................................................................
3
HTTP
STATUS
KODLARI:
...................................................................................................................................
4
HTTP
Methods
......................................................................................................................................................
4
GET
ve
POST
arasındaki
Farklar
.................................................................................................................................
5
WEB
API
Projesi
...................................................................................................................................................
5
Web
API
Action
Result
Kullanımı
...............................................................................................................................
7
VOID
Method
Kullanımı
...................................................................................................................................................................
7
ReturnType
Kullanımı
(Custom
Object)
...................................................................................................................
8
HttpResponseMessage
Kullanımı
.............................................................................................................................
10
IHttpActionResult
Kullanımı
......................................................................................................................................
10
WEB
API
Model
Validation
.............................................................................................................................
16
CORS
(Cross
Origin
Request
Sharing)
........................................................................................................
17
Same Origin
....................................................................................................................................................................
17
CORS
WebConfig
Ayarı
.................................................................................................................................................
17
Attribute
Based
Routing
.................................................................................................................................
19
Webapi
Sık
Kullanılan
Attributelar
.........................................................................................................................
20
Web
Api
Authentication
.................................................................................................................................
20
OWIN
Nedir
......................................................................................................................................................................
21
OAuth
Nedir
.....................................................................................................................................................................
21
Claim
Based
Authentication
.......................................................................................................................................
22
Token
Based
Authentication
......................................................................................................................................
22
Token
Based
Authentication
Çalışma
Prensibi
....................................................................................................
22
Token
Based
Authentication
Uygulama
....................................................................................................
23
Owin
Entegrasyonu
.......................................................................................................................................................
23
Cors
Konfigürasyonu
....................................................................................................................................................
24
Authorization
Server
Konfigürasyonu
....................................................................................................................
25
Web
Api
Resource
Konfigürasyonu
.........................................................................................................................
26
Access_Token
LocalStorage
Barındırma
................................................................................................................
26
HttpHeaders
da
Access_Token
Konfigürasyonu
..................................................................................................
26
WEB
API
ODATA
................................................................................................................................................
27
OData
Global
olarak
Register
Etme
..........................................................................................................................
27
[WEB
API]
SOA’NIN
FAYDALARI
§ İş birimi için operasyon maliyeti düşüktür. (Servisler özerk tanımlanır) (Anatomy özelliği)
§ Endüstriyel olarak standartmış ilkeleri önerir. (Uyumluluk ve Entegrasyon)
§ İş süreçlerinde değişikliklere kolayca adepte olunur, pazara yeni iş fonsiyonelliklerini hızlı sunabilme imkanı
vardır
§ Yeni sistemlere az eforla bağlanmak mümkündür. İş ortağı firmalarla entegrasyon kolaydır.
Google Maps Google haritalar servisini kullanmak ve haritalar ile ilgili [Link]
işlemler yapmak için kullanılır.
Switching
101 Anahtarlama Protokolü
Protocols
Non-
203 Authoritative İstek Yetersiz bilgi içeriyor
Information
Multiple
300 Çok Seçenek
Choices
Moved
301 Kalıcı Taşındı
Permanently
Moved
302 Geçici Taşındı
Temporarily
400 Bad Request Kötü İstek, (yapılan isteğin sunucu daki formata uymadığı durumlarda kullanışlır, ModelValidation)
401 Unauthorized Kişinin kaynağa erişim yetkisi olmadığı durumlarda tercih edilir.
Payment
402 Ödeme gerekli, Ödeme işlemlerini servis üzerinden yaptığımız durumlarda istemciye dönen bir mesajdır.
Required
403 Forbidden Kaynak var ama erişmek için izin var fakat sunucu isteği red ediyor.
Method not
405 Kaynağa yapılan HttpMethod fiili mevcut değil
Allowed
Unsupported
415 İstemci tarafından desteklenemeyen medya formatı
Media type
Internal Server
500 Sunucuda Hata oluştu
Error
Not
501 Sunucudaki kaynak içinde tanımlanmış method içine kod yazılmadığı durumlarda oluşur.
Implemented
Service
503 Sunucuya erişilemiyor (Ya sunucu kapasitesini aştı yada şuan çöktü)
Unavaible
HTTP Methods
GET : Kaynağa url üzerinden erişmek için kullanılan http Method’tur.
POST : İşlenecek verileri belirli bir kayna URI göndermemizi sağlar. Şuan sunucuda bulunmayan ilk defa işlenecek
veriler için tercih edilir.
PUT : Belirtilen kaynak URI de işlenecek olan verilen yüklemesini sağlar. Veri güncelleme işlemlerinde tercih edilir.
Post’a göre daha performanslı çalışır.
DELETE : Belirtilen kaynak URI de silinecek olan veriler için tercih edilir.
[WEB
API]
HEAD : GET isteğine benzer fakat, sadece istek ile ilgili veya cevap ile ilgili bilgiler head istediğinde taşınır.
GET POST
BACK BUTTON Geri Butonuna basmanın sunucu ve istemci arasındaki haberleşmeye bir zararı
Veri yeniden işlenecektir. (DİKKAT)
yoktur
CACHED
Veri ramde tutulabilir. Veri ramde tutulamaz
Encoding type
application/x-www-form-urlencoded tipinde istekler yapılabilir. application/x-www-form-urlencoded veya multipart/form-data
History
Veriler tarayıcının geçmişinde saklı kalır Veriler Tarayıcı geçmişinde saklanmaz
Security Post ta göre veri taşımasında daha az güvenli bir yöntemdir. Çünkü veri URL
üzerinden taşınır. Sensitive veri veya parola gibi önemli verilerimizi taşımak için Hassas verilerimizin iletiminde tercih edilir.
tercih edilmez
Visibility
Veri taşıma sırasında URL den görünür. Veri URL üzerinden görüntülenemez.
Daha sonra gelen pencerenden Empty project seçilerek alttaki seçim kutusundan WEB API seçeneğini işaretleyin.
Bu seçenek oluşturulan proje içerisinde Web API kullanımına uygun kütüphanelerin referans edilmesini
sağlayacaktır. Ayrıca Empty template’ini seçtiğimizden dolayı boş bir Web API projesi oluşturacağız.
[WEB
API]
Daha sonra açılan projeden Controllers klasörü üstüne gelip. Add Controller seçeneklerini seçerek. Aşağıda açılan
penceren Web API 2 Controller Boş template seçimi yaparak açılan pencereden TestController ismini vererek
projemize api controller açmış oluruz.
[WEB
API]
Örneğimizde gördüğünüz gibi TestController ile uygulamamız için web isteklerimizi yakalayacağımız bir yapı
oluşturduk. TestController içerisindeki kodları incelediğimizde ApiController sınıfından miras alarak oluşturulduğunu
görebiliriz. ApiController sınıfı bir apinin göstermesi gereken özelliklere sahiptir.
ApiControllerdan miras alan TestController ile belirli dönüş tipleri kullanarak web sunucusundan istemciye belirli
medya tiplerinde sonuç gönderilir. Şimdi bu parta gelen istekleri işleyeceğimiz Action Result tiplerinden ve bu
istekleri yapmamızı sağlayan methodların kullanımından bahsedeceğiz.
[Link]
//
HttpGet
ile
URL
üzerinden
HttpRequest
yapacağımızı
söyledik.
//
localhost:8xxx:api/Test
URL
postman
ile
istekte
bulunun
dönen
sonucu
görelim
[HttpGet]
public
void
Data()
{
}
Chrome üzerine kurabileceğimiz bir eklenti olup, http trafiği üzerinde işlem yapabilmemizi sağlayan postmani
kuruyoruz Web sunucusuna İsteklerimizi postman ile göndereceğiz.
[WEB
API]
Yukarıda ki gibi HttpGet fiili seçilerek url’den istekde bulunduk. Status 204 No Content döndüğüne dikkat edelim.
İsteğimize 27 ms de cevap verilmiştir. HttpResponseMessage yoktur. Headers kısmında sunucudan aldığımız
bilgiler ise aşağıdaki gibidir. Headers Web-Server ile Web-Client arasında her bir haberleşmede HttpProtokolü
üzerinden taşınan bilgilerin gönderildiği HttpVerb’tür.
Cache-Control →no-cache
Date →Sun, 26 Feb 2017 05:49:29 GMT
Expires →-1
Pragma →no-cache
Server →Microsoft-IIS/10.0
X-AspNet-Version →4.0.30319
X-Powered-By →[Link]
[Link]
//
HttpGet
Verb
yazmamamıza
rağmen
bu
istek
HTTPGET
isteği
olarak
sunucu
tarafından
kabul
[Link]
ise
Method
ismi
olarak
HTTPVERB
olan
GET,POST,PUT,DELETE
kullanmamız
[Link]ğın
üzerine
HTTPVERBS
attributelerini
yazmamıza
gerek
yoktur.
//
localhost:8xxx:api/Test
URL
postman
ile
istekte
bulunun
dönen
sonucu
görelim
public
List<PersonModel>
GetPersons()
{
return
PersonList;
}
Uyarı : Eğer bir controller içersinde aynı method imzasına sahip iki farklı aynı fiilde bir kaynak varsa apicontroller hangi kaynağın istemci
tarafından istendiğini bilemez. Bu sebeple Multiple action were Found hatası verir. Bu durumda [Link] dosyasından route
düzenlemesi yapılmalıdır.
[WEB
API]
Yukarıda görüldüğü gibi route dosyamızda herhangi bir ayara yapmadığımızda sunucuya yaptığımız istek bize
Internal Server Error Status Code ile geri dönüş yapmıştır.
WebApiConfig dosyasında yukarıda yapılan konfigürasyon işleminden sonra web sunucuna istekte bulunuyoruz.
[WEB
API]
Yukarıdaki gibi HttpResponse Body’sinde XML medya tipinde verilerimizin döndüğünü gördük.
Uyarı : Eğer herhangi bir MediaType Formatter ayarı yapmadıysanız, WebApi varsayılan da veriyi XML medya tipinde serilize edecektir.
HttpResponseMessage Kullanımı
HttpResponseMessage döndüren methodlar gelen isteğin fiiline göre HttpGet, HttpPost, HttpPut, HttpDelete
HttpVerbs attributeleri ile kullanılabilir. Kaynağa ulaşıldığı takdir de HttpStatus Code ve HttpResponseMessage
olarak XML ve JSON, PlainText, Html vs medya formatlarından biri halinde veri istemciye gönderilir. ReturnType
methodlardan farkı erişilen kaynaktaki logic’e göre HttpStatusCode döndürebilir veya Response olarak taşınacak
verinin medya tipini belirleyebiliriz. [Link]() methodu ile kedimiz gelen talebe bir cevap
üretebiliriz. Yani HttpResponseMessage dönüş tipi sayesinde gelen talebe http protokolü üzerinden direk bir cevap
mesajı oluşturmamızı sağlar ve bu sayede gönderilecek olan cevap üzerinden bir çok kontrol yapabilme imkanımız
olur.
[Link]
//
localhost:8xxx:api/Test/getcontent
URL
postman
ile
istekte
bulunun
dönen
sonucu
görelim
public
HttpResponseMessage
GetContent()
{
HttpResponseMessage
response
=
[Link]([Link],
"value");
[Link]
=
new
StringContent("hello",
[Link]);
[Link]
=
new
CacheControlHeaderValue()
{
MaxAge
=
[Link](20)
};
return
response;
}
[Link] ile isteğe dönecek olan cevapı string tipinde döndürüyoruz. Kayanağa yapılan isteği de 20
dakikalığına cache’e alıyoruz. Tabi burada string Content yerine medya tipi belirtilerek kendi döndürmek istediğimiz
modelleri de cevap olarak döndürebiliriz.
Response
Yukarı da görüldüğü gibi cevap text/plain dönüş tipi olarak gelmiştir. Kaynağın cache’ten okunacağı maksimum
süre 20 dk olarak sunucudan cevap olarak gönderilmiştir. Bu bilgiler sunucudan gelen cevabın Headers ile
gönderilken. Hello cevabı ResponseBody dediğimiz cevabın gövdesinde gönderilmiştir.
IHttpActionResult Kullanımı
IHttpActionResult olarak döndüren methodlar gelen isteğin fiiline göre HttpGet, HttpPost, HttpPut, HttpDelete
HttpVerbs attributeleri ile kullanılabilir. Kaynağa ulaşıldığı takdirde HttpStatus Code ve HttpResponseMessage
olarak XML ve JSON, PlainText, Html vs medya formatlarından biri halinde veri istemciye gönderilir.
HttpResponseMessage veri tipi ile döndürebileceğimiz cevapları bu tip ile döndürmemiz mümkündür. Web API 2.0
ile birlikte sıkça kullanılan async çalışan bu dönüş tipi genelde tercih edilmektedir. Tercih edilmesinin sebebine
gelince;
• HttpResponseMessage Fabrikası olarak kullanılan bir arayüzdür. Bu arayüzden kendi medya
formatlarımızı döndürebiliriz.
[WEB
API]
• Bu arayüzden implemente olmuş farklı sınıflar sayesinde unit testi daha kolay yapılan ve birbirlerinden
tümüyle soyutlanmış olan sınıflar ile çalışabilme imkanı sunar.
• Medya tipini döndüren sınıfın logiclerinden controller’ın action’ı içerisindeki yapıyı tümü ile birbirinden
ayırarak temiz bir kullanım sağlar. Ve alt seviye detaylardan controller içindeki actionları kurtarmış olur.
Tek bir method içeririr.
C#
public
interface
IHttpActionResult
{
Task<HttpResponseMessage>
ExecuteAsync(CancellationToken
cancellationToken);
}
C#
public
class
TextResult
:
IHttpActionResult
{
string
_value;
HttpRequestMessage
_request;
public
TextResult(string
value,
HttpRequestMessage
request)
{
_value
=
value;
_request
=
request;
}
public
Task<HttpResponseMessage>
ExecuteAsync(CancellationToken
cancellationToken)
{
var
response
=
new
HttpResponseMessage(){
Content
=
new
StringContent(_value),
RequestMessage
=
_request
};
return
[Link](response);
}
}
Not: Yukarıdaki örnek ile IHttpActionResult arayüzünü kendi sınıflarımıza implement ederek kendi dönüş tiplerimizi tanımlayabildiğimizi görmüş
olduk.
C#
Postman programı ile api/test/getcustomtype URI istek yaparak dönen sonucun aşağıdaki gibi oluştuğunu
gözlemleyelim.
[Link]
HTTP/1.1
200
OK
[WEB
API]
Content-‐Length:
5
Content-‐Type:
text/plain;
charset=utf-‐8
Server:
Microsoft-‐IIS/8.0
Date:
Mon,
27
Jan
2014
08:53:35
GMT
hello
Bunun dışında IHttpActionResult
tipinde yapılan isteklerde aşağıdaki dönüş tipleri daha önceden tanımlı olduğu
için action içerisinde daha temiz kod yazabilme imkanı sağlamaktadır.
Şimdi bir örnek üzerinden IHttpActionResult
arayüzünün dönüş tiplerini kullanarak nasıl daha temiz kodlar
yazacağımızı görebileceğimiz bir örnek yapalım. Günlük haber girişi yaptığımız bir API mizin olduğunu ve buradan
bir çok haber sağlayıcına son dakika haberleri verdiğimizi düşünelim. NewsController adında bir ApiController
üzerinden JSON ve XML medya tiplerinde veri çıkış noktası (endpoint) açalım. Haberlerin dışarı çıkartacağımız
model
[Link]
namespace
[Link]
{
public
class
NewsModel
{
public
int
NewsID
{
get;
set;
}
[Required(ErrorMessage
="Haber
Başlığı
Giriniz")]
public
string
Name
{
get;
set;
}
[Required(ErrorMessage
=
"Haber
Kısa
içeriği
giriniz"),MaxLength(100,ErrorMessage
="100
karakter
girebilirsiniz")]
public
string
Content
{
get;
set;
}
[Required(ErrorMessage
=
"Haber
içeriği
giriniz.")]
public
string
FullContent
{
get;
set;
}
[IgnoreDataMember]
//
Eğer
modelden
dışarı
serilize
olmasını
istemediğimiz
üye
var
ise
bu
attribute
kullanılır.
public
DateTime
PostDate
{
get;
set;
}
public
int
CID
{
get;
set;
}
}
}
Aşağıdaki kod ise dışarı çıkartıcağımız modelin Entity’sidir. Entityleri dışarıya direk çıkarmamızın sebebi
tablolarımızdaki her bir alanın dışarı çıkmasını istememek veya dışarı çıkan verilerimizin güvenlik açısından
tablodaki sütün alanlarının isimleri ile aynı olmamasını sağlamaktır. Bu sayede veritabanına yapılan herhangi bir
[WEB
API]
atağa karşı yazılımsal olarak bir açık oluşturmamış olacağız. Bunun dışında validasyon işlemlerimizi modeller
üzerinden yapıp Entityleri kirletmemektir. Kurumsal Projelerde bu tarz yapılar için Modellerimizi Entitylere çeviren
yada tam tersi işlem yapan Mapper’lar kullanılabilir.
[Link]
namespace
[Link]
{
public
class
News
{
[Key]
public
int
ID
{
get;
set;
}
public
string
Title
{
get;
set;
}
public
string
Short
Content
{
get;
set;
}
public
string
Body
{
get;
set;
}
public
int
Category
ID
{
get;
set;
}
public
DateTime?
Create
Date
{
get;
set;
}
[Foreign
Key("Category
ID")]
public
virtual
News
Category
Category
{
get;
set;
}
}
}
Son olarak CodeFirst ile oluşturduğumuz yapımızın veritabanı bağlantıları için aşağıdaki kodu da [Link]
içerisinde yazdık.
[Link]
public
class
ProjectContext:DbContext
{
public
ProjectContext()
{
[Link]
=
"Server=.;Database=NewsDb;uid=sa;pwd=123";
}
public
DbSet<News>
News
{
get;
set;
}
public
DbSet<News
Category>
Categories
{
get;
set;
}
}
Aşağıdaki action da ise haberlerimizi liste olarak veritabanımızdan çeken GetNews adında bir method ile endpoint
oluşturmuş olduk.
[Link]
exception
oluşmaz
var
model
=
[Link](a
=>
new
NewsModel
{
Name
=
[Link],
Content
=
[Link],
CID
=
[Link],
FullContent
=
[Link]
}).ToList();
return
Ok(model);
}
Şimdi ise Postman kullanarak ilgili kaynağa Get isteğinde bulunarak verilerimizin geldiğini gözlemleyelim.
Gördüğümüz gibi Web Server ‘a istek yaparken application/json medya formatında veri isteğinde bulunduk ve
HttpStatus Code : 200 Ok döndü ve Response Body’sinde ise Json olarak verinin döndüğünü görüyoruz.
Şimdi ise NewsApiController altına PostNews adında bir action oluşturup, server-side validasyon yaparak veri
kaynağımıza nasıl veri göndereceğimizin örneğini yapalım.
[Link]
public
IHttpActionResult
PostNews(NewsModel
model)
{
ProjectContext
db
=
new
ProjectContext();
if
([Link])
{
var
entity
=
new
News();
[Link]
=
[Link];
[Link]
=
[Link];
[Link]
=
[Link];
[Link]
=
[Link];
[WEB
API]
[Link](entity);
[Link]();
return
Json(model);
}
return
BadRequest(ModelState);
}
Evet yukarıda ki sonuçtan anlaşıldığı gibi form üzerinden gönderdiğimiz model başarılı bir şekilde veri kaynağımıza
ulaştı. Şimdi de modelimizdeki zorunlu olanları istediğimiz formatta sunucuya göndermediğimiz durumda web
sunucunun nasıl bir HttpResponseMessage döndüreceğini gözlemleyelim.
[WEB
API]
[Link]
public
class
ModelValidAttribute:ActionFilterAttribute
{
public
override
void
OnActionExecuting(HttpActionContext
actionContext)
{
if
(![Link])
{
[Link]
=
[Link]([Link],
[Link]);
}
}
}
ActionFilterAttribute
:
Her hangi bir action’a girmeden önce actionfilter attribute ile model kontrolü yapıp buna
göre api’den farklı HttpResponseMessage’lar döndürmemize olanak tanır. OnActionExecuting ve
OnActionExecuted tiye virtual tanımlanmış iki methodu vardır. Kendi sınıflarımızda ActionFilterAttribute den miras
alarak methdolarımızın nasıl çalışacağını belirtebiliriz.
HttpActionContext
sınıfı ise o an api de istek de bulunduğumuz action kapsamına girip, bu kapsama parametre
olarak geçilen modelin validasyonunu kontrol edebilir. Yukarıda validasyon kontrolünden geçemediğimiz durumda
ModelState HttpStatus Code 400 olarak gönderen bir kullanım örneği görmekteyiz. yönetme imkanı sağlayacağız.
Aşağıdaki örnek bu işlemi nasıl yapacağımız ile ilgili kodları içermektedir.
[WEB
API]
[Link]
[ModelValid]
public
IHttpActionResult
PostNews(NewsModel
model)
{
var
entity
=
new
News();
[Link]
=
[Link];
[Link]
=
[Link];
[Link]
=
[Link];
[Link]
=
[Link];
[Link](entity);
[Link]();
return
Json(model);
}
Same Origin
Uygulama aynı domainde ise aynı origindedir. Aynı domainde olan uygulamalar arasında kaynak paylaşımı için
özel bir konfigürasyon yapma ihtiyacı yoktur. Aşağıda aynı origin de olan kaynaklara yer verilmiştir.
1. [Link] - domain
2. [Link] - port
3. [Link] sub-domain
Aşağıdaki örnek ile farklı domainler üzerinden kaynak paylaşımı yapmak için gerekli olan konfigürasyon
adımlarından bahsedilecektir. NewsApi uygulaması üzerinden örneklere yer verilecektir.
[Link]
<[Link]>
[WEB
API]
<httpProtocol>
<customHeaders>
<add
name="Access-‐Control-‐Allow-‐Origin"
value="*"/>
<add
name="Access-‐Control-‐Allow-‐Methods"
value="OPTIONS,GET,POST,PUT,DELETE,HEAD"
/>
<add
name="Access-‐Control-‐Allow-‐Headers"
value="Content-‐Type,Accept"/>
</customHeaders>
</httpProtocol>
</[Link]>
Yukarıdaki gibi WebConfig dosyasında yapacağımız bu ayar ile uygulama bazlı kaynak paylaşımı yapmış oluruz.
Access-‐Control-‐Allow-‐Origin anahtar değerine karşılık gelen * tüm domainler’e kaynak paylaşımı izni
verdiğimizi gösteriyor. Access-‐Control-‐Allow-‐Methods
ile api üzerinden izin verilen tüm HttpVerbler global olarak
belirtilmiştir. Access-‐Control-‐Allow-‐Headers
anahtar değeri ile de web sunucusuna yapılan isteklerde header da
izin verilen değerler aralarına virgül (,) konularak yazılır. Web Api bir kullanıcının hangi niyetle kaynak talep ettiğini
anlamak için talebin(HttpRequest) Header bilgilerini kontrol eder. Aşağıda Headers olarak tanımlayabileceğimiz
değerler ve bunların ne anlam ifade ettiklerinden bahsedilmiştir.
[Link]
protected
void
Application_Start()
{
[Link]([Link]);
//ilk
parameter
izin
verilen
domainler
//ikinci
parameter
izin
verilen
methodlar
//son
parameter
izin
verilen
headers
bilgisi
var
cors
=
new
EnableCorsAttribute("*",
"*",
"*");
[Link](cors);
}
[WEB
API]
Eğer yukarıdaki gibi [Link] Web Api Cors kütüphanesini yüklerseniz WebConfig dosyasında herhangi bir
yapılandırma yapmadan, uygulama genelinde CORS ayarlarını [Link] içerisine yukarıdaki kodlar ile
yapabilirsiniz. Eğer sadece ilgili method için özel bir yapılandırma yapmak istiyorsanız bu durumda aşağıdaki gibi
kullanmalısınız.
[Link]
[ModelValid][EnableCors("*","*","*")]
public
IHttpActionResult
PostNews(NewsModel
model)
{
//Kodlar
return
Json(model);
}
[Link]
[Route("haberler")]
public
IHttpActionResult
GetNews()
{
[Link]
=
false;
var
model
=
[Link]().Select(a
=>
new
NewsModel
{
Name
=
[Link],
Content
=
[Link],
CID
=
[Link],
FullContent
=
[Link]
}).ToList();
return
Ok(model);
}
[Link]
namespace
[Link]
{
[RoutePrefix("haberapi")]
public
class
NewsApiController
:
ApiController
{
}
}
OWIN Nedir
Öncelikle OWIN kelimesinin Open Web Interface for .Net (.Net için açık web arayüzü) olduğuyla söze başlayalım.
Bir teknoloji olmaktan ziyade bir standart olan OWIN, .Net web sunucularıyla, yine .Net ile geliştirilmiş web
uygulamalarının birbirleriyle nasıl iletişim kuracağını anlatmakta kullanılan bir arayüzü tanımlamaktadır. Bu
tanımlamadaki amaç ise sunucu ve uygulamaları birbirlerinden net çizgilerle ayırmak ve uygulamaları sunuculardan
bağımsız hale getirmektir.
OAuth Nedir
En kısa tanımla OAuth, kullanıcıların üyesi oldukları bir site yada platformun şifresini üye
oldukları başka bir web sitesi yada platformla paylaşmadan, izin verdiği bilgilere diğer
site tarafından ulaşılmasını sağlayan bir kimlik doğrulama protokolüdür.
[WEB
API]
5. Bunun dışında Web Api tarafında Token Based Authentication yapısını [Link] ile
yapmaktayız.
Owin Entegrasyonu
Bu kısımda Owin middleware kullanarak StartUp dosyası oluşturma ve Global olarak uygulama bazlı konfigüre
etmek ile ilgili ayarlarımızı yapacağız. Öncelikle OwinStartup sınıfı oluşturmak için aşağıdaki adımları takip edelim.
Projemiz Sağ Click -> Add New Item -> Arama kutusuna OWIN yazarak OWINStartUp class projemize ekleriz.
Daha sonra StartUp sınıfımız içerisinde aşağıdaki kodları yazarak Owin middleware ile uygulamamızın
başlatılmasını sağlıyoruz.
[WEB
API]
[Link]
public
class
Startup
{
public
void
Configuration(IAppBuilder
app)
{
//IAppBuilder
uygulama
oluşturucu
arayüz.
OWIN
Assembly’sinden
gelir.
HttpConfiguration
=
new
HttpConfiguration();
//ConfigureOAuth();
method
ile
uygulamamızda
Open
Authentication
protokolü
ile
kimlik
doğrulama
yapacağımızı
söyledik.
[Link]
Assembly
ile
projemize
refereans
vermiştik.
ConfigureOAuth(app);
//UseWebApi
ile
global
olarak
yapılan
konfigürasyonların
tanımlanmasını
belirtmiş
olduk.
[Link](httpConfiguration);
[Link](httpConfiguration);
}
}
[Link]
public
class
Startup
{
private
void
ConfigureOAuth(IAppBuilder
appBuilder)
{
OAuthAuthorizationServerOptions
=
new
OAuthAuthorizationServerOptions()
{
TokenEndpointPath
=
new
[Link]("/token"),
//
token
alacağımız
path'i
belirtiyoruz
AccessTokenExpireTimeSpan
=
[Link](1),
AllowInsecureHttp
=
true,
Provider
=
new
CustomAuthorizationServerProvider()
};
//AppBuilder'a
token
üretimini
gerçekleştirebilmek
için
ilgili
authorization
ayarlarımızı
veriyoruz.
[Link](oAuthAuthorizationServerOptions);
//Authentication
type
olarak
ise
Bearer
Authentication'ı
kullanacağımızı
belirtiyoruz.
//Bearer
token
OAuth
2.0
ile
gelen
standartlaşmış
token
türüdür.
//Herhangi
kriptolu
bir
veriye
ihtiyaç
duymadan
client
tarafından
token
isteğinde
bulunulur
ve
server
belirli
bir
expire
date'e
sahip
bir
access_token
üretir.
//Bearer
token
üzerinde
güvenlik
SSL'e
dayanır.
//Bir
diğer
tip
ise
MAC
token'dır.
OAuth
1.0
versiyonunda
kullanılıyor,
hem
client'a,
hemde
server
tarafına
implementasyonlardan
dolayı
ek
maliyet
çıkartmaktadır.
Bu
maliyetin
yanı
sıra
ise
Bearer
token'a
göre
kaynak
alış
verişinin
biraz
daha
güvenli
olduğu
söyleniyor
çünkü
client
her
request'inde
veriyi
hmac
ile
imzalayıp
verileri
kriptolu
bir
şekilde
göndermeleri
gerektiği
için.
[Link](new
OAuthBearerAuthenticationOptions());
}
}
Cors Konfigürasyonu
Bu Web Client ile Web Server farklı domainler üzerinden olacağından, ve birbileri arasında kaynak paylaşımı
yapacaklarından, CORS konfigürasyonu yapmamız gerekmektedir. Aşağıda [Link] da uygulama bazlı Cors
ayarlarına yer verilmiştir.
[WEB
API]
[Link]
protected
void
Application_Start()
{
[Link]([Link]);
//ilk
parameter
izin
verilen
domainler
//ikinci
parameter
izin
verilen
methodlar
//son
parameter
izin
verilen
headers
bilgisi
var
cors
=
new
EnableCorsAttribute("*",
"*",
"*");
[Link](cors);
}
[Link]
public
class
CustomAuthorizationServerProvider:
OAuthAuthorizationServerProvider
{
public
override
async
Task
ValidateClientAuthentication(OAuthValidateClientAuthenticationContext
context)
{
[Link]();
}
public
override
async
Task
GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext
context)
{
[Link]("Access-‐Control-‐Allow-‐Origin",
new[]
{
"*"
});
//
Kullanıcının
access_token
alabilmesi
için
gerekli
validation
işlemlerini
yapıyoruz.
if
([Link]
==
"User"
&&
[Link]
==
"123")
{
//
Oturum
Açan
kullanıcının
talep
edildiğinde
erişilmesi
istenen
claimlerini
oluşturuyoruz.
Kullanıcıya
name
ve
role
özellikleri
verdik.
Authenticated
olan
kullanıcıdan
bu
bilgileri
talep
edebiliriz.
var
identity
=
new
ClaimsIdentity([Link]);
[Link](new
Claim("name",
[Link]));
[Link](new
Claim("role",
"user"));
[Link](identity);
}
else
{
//
Eğer
kullanıcı
validasyondan
geçemezse
bu
durumda
erşim
yetkisi
olmadığına
dair
invalid_grant
ile
401
UnAuthorized
HttpStatusCode
Response
Body
olarak
gönderilir.
[Link]("invalid_grant",
"Kullanıcı
adı
veya
şifre
yanlış.");
}
}
}
[WEB
API]
[Link]
public
class
TestController
:
ApiController
{
[Authorize]
public
IHttpActionResult
Get()
{
return
Json("OK");
}
}
[Link]
$("#btnlogin").click(function
()
{
var
User
=
new
Object();
User.grant_type
=
"password"
[Link]
=
"User";
[Link]
=
"123";
$.ajax({
url:
"[Link]
type:
"POST",
dataType:
"json",
data:
User,
success:
function
(response)
{
[Link](response.access_token);
}
})
})
[Link]
$("#getInfo").click(function
()
{
var
access_token
=
[Link](“accessToken”)
$.ajax({
url:
"[Link]
beforeSend:
function
(xhr)
{
[Link]('Authorization',
'Bearer
'
+
access_token);
},
type:
"GET",
dataType:
"json",
success:
function
(response)
{
[Link](response);
},
error:
function
(error)
{
[Link](error);
[WEB
API]
},
})
})
[Link]
public
class
WebApiApplication
:
[Link]
{
protected
void
Application_Start()
{
[Link]([Link]);
//uygulama
genelinde
bu
ayarı
kullanabiliriz
[Link]();
}
}
Daha Sonra OData Kullanmak istediğiniz actionların Dönüş tipini IQuaryable
yapmalıyız. İlgili actionların üzerine
ise [Queryable] attribute tanımlayarak artık querystring ile parametre bazlı sorgulama yapabiliriz. Aşağıda örnek
bir kullanım mevcuttur.
[Link]
[WEB
API]