Kimlik Doğrulama
Nette, sitelerimizde kimlik doğrulama programlamanın bir yolunu sunar, ancak bizi hiçbir şeye zorlamaz. Uygulama tamamen
bize bağlıdır. Nette, yalnızca kullanıcıyı istediğimiz şekilde doğrulayan tek bir authenticate
metodu
gerektiren Nette\Security\Authenticator
arayüzünü içerir.
Bir kullanıcının doğrulanabileceği birçok olasılık vardır. En yaygın doğrulama yöntemi şifre iledir (kullanıcı adını veya e-postasını ve şifresini sağlar), ancak başka yollar da vardır. Bazı sitelerde “Facebook ile Giriş Yap” veya Google/Twitter/GitHub ile giriş yapma gibi düğmeleri biliyor olabilirsiniz. Nette ile herhangi bir giriş yöntemine sahip olabiliriz veya bunları birleştirebiliriz. Bu tamamen bize bağlıdır.
Normalde kendi kimlik doğrulayıcımızı yazardık, ancak bu basit küçük blog için yapılandırma dosyasında saklanan
şifre ve kullanıcı adına göre giriş yapan yerleşik kimlik doğrulayıcıyı kullanacağız. Test amaçları için
kullanışlıdır. Bu nedenle, config/common.neon
yapılandırma dosyasına aşağıdaki security bölümünü
ekleyeceğiz:
security:
users:
admin: secret # kullanıcı 'admin', şifre 'secret'
Nette, DI konteynerinde otomatik olarak bir servis oluşturur.
Giriş Formu
Şimdi kimlik doğrulamamız hazır ve giriş yapmak için kullanıcı arayüzünü hazırlamamız gerekiyor. Bu nedenle, SignPresenter adlı yeni bir presenter oluşturalım:
- giriş formunu görüntüler (giriş adı ve şifre ile)
- form gönderildikten sonra kullanıcıyı doğrular
- oturumu kapatma seçeneği sunar
Giriş formuyla başlayalım. Presenter'larda formların nasıl çalıştığını zaten biliyoruz. Bu nedenle bir
SignPresenter
presenter'ı oluşturacağız ve createComponentSignInForm
metodunu yazacağız. Şöyle
görünmelidir:
<?php
namespace App\Presentation\Sign;
use Nette;
use Nette\Application\UI\Form;
final class SignPresenter extends Nette\Application\UI\Presenter
{
protected function createComponentSignInForm(): Form
{
$form = new Form;
$form->addText('username', 'Kullanıcı adı:')
->setRequired('Lütfen kullanıcı adınızı girin.');
$form->addPassword('password', 'Şifre:')
->setRequired('Lütfen şifrenizi girin.');
$form->addSubmit('send', 'Giriş yap');
$form->onSuccess[] = $this->signInFormSucceeded(...);
return $form;
}
}
Kullanıcı adı ve şifre için alanlar vardır.
Şablon
Form, in.latte
şablonunda işlenecektir:
{block content}
<h1 n:block=title>Giriş Yap</h1>
{control signInForm}
Giriş Callback'i
Ardından, form başarıyla gönderildikten hemen sonra çağrılacak olan kullanıcı girişi için callback'i ekleyeceğiz.
Callback yalnızca kullanıcının doldurduğu kullanıcı adını ve şifreyi alır ve bunları kimlik doğrulayıcıya iletir. Giriş yaptıktan sonra ana sayfaya yönlendiririz.
private function signInFormSucceeded(Form $form, \stdClass $data): void
{
try {
$this->getUser()->login($data->username, $data->password);
$this->redirect('Home:');
} catch (Nette\Security\AuthenticationException $e) {
$form->addError('Yanlış kullanıcı adı veya şifre.');
}
}
User::login() metodu, kullanıcı adı ve şifre yapılandırma dosyasındaki verilerle eşleşmezse bir istisna atar. Zaten bildiğimiz gibi, bu kırmızı bir hata sayfasına veya üretim modunda bir sunucu hatası hakkında bilgi veren bir mesaja neden olabilir. Ancak bunu istemiyoruz. Bu nedenle bu istisnayı yakalarız ve forma güzel, kullanıcı dostu bir hata mesajı iletiriz.
Formda bir hata oluştuğunda, form içeren sayfa yeniden çizilir ve formun üzerinde kullanıcıya yanlış giriş adı veya şifre girdiğini bildiren güzel bir mesaj görüntülenir.
Presenter'ların Güvenliğini Sağlama
Gönderi ekleme ve düzenleme formunu güvence altına alacağız. Bu, EditPresenter
presenter'ında
tanımlanmıştır. Amaç, oturum açmamış kullanıcıların sayfaya erişimini engellemektir.
Presenter yaşam döngüsünün
hemen başında çalışan startup()
metodunu oluşturacağız. Bu metot, oturum açmamış kullanıcıları giriş
sayfasına yönlendirir.
public function startup(): void
{
parent::startup();
if (!$this->getUser()->isLoggedIn()) {
$this->redirect('Sign:in');
}
}
Bağlantıları Gizleme
Yetkisiz bir kullanıcı artık create veya edit sayfasını göremez, ancak yine de onlara bağlantıları
görebilir. Bunları da gizlemeliyiz. Böyle bir bağlantı app/Presentation/Home/default.latte
şablonundadır ve
yalnızca oturum açmış kullanıcılar tarafından görülmelidir.
Bunu n:if
adlı bir n:attribute kullanarak gizleyebiliriz. Bu koşul false
ise, içerik dahil
tüm <a>
etiketi gizli kalacaktır.
<a n:href="Edit:create" n:if="$user->isLoggedIn()">Gönderi oluştur</a>
bu, aşağıdaki gösterimin kısaltmasıdır (tag-if
ile karıştırılmamalıdır):
{if $user->isLoggedIn()}<a n:href="Edit:create">Gönderi oluştur</a>{/if}
Aynı şekilde app/Presentation/Post/show.latte
şablonundaki bağlantıyı da gizleyeceğiz.
Giriş Bağlantısı
Aslında giriş sayfasına nasıl ulaşırız? Ona yönlendiren hiçbir bağlantı yok. Öyleyse onu @layout.latte
şablonuna ekleyelim. Uygun bir yer bulmaya çalışın – hemen hemen her yerde olabilir.
...
<ul class="navig">
<li><a n:href="Home:">Makaleler</a></li>
{if $user->isLoggedIn()}
<li><a n:href="Sign:out">Çıkış yap</a></li>
{else}
<li><a n:href="Sign:in">Giriş yap</a></li>
{/if}
</ul>
...
Kullanıcı oturum açmamışsa, “Giriş yap” bağlantısı görüntülenir. Aksi takdirde, “Çıkış yap”
bağlantısı görüntülenir. Bu eylemi SignPresenter
'a da ekleyeceğiz.
Kullanıcıyı oturumu kapattıktan hemen sonra yönlendirdiğimiz için herhangi bir şablona gerek yoktur. Oturumu kapatma şöyle görünür:
public function actionOut(): void
{
$this->getUser()->logout();
$this->flashMessage('Başarıyla çıkış yapıldı.');
$this->redirect('Home:');
}
Yalnızca logout()
metodu çağrılır ve ardından başarılı oturum kapatmayı onaylayan güzel bir mesaj
görüntülenir.
Özet
Giriş yapmak ve ayrıca kullanıcının oturumunu kapatmak için bir bağlantımız var. Doğrulama için yerleşik kimlik doğrulayıcıyı kullandık ve giriş bilgileri yapılandırma dosyasındadır, çünkü bu basit bir test uygulamasıdır. Ayrıca düzenleme formlarını da güvence altına aldık, böylece yalnızca oturum açmış kullanıcılar gönderi ekleyebilir ve düzenleyebilir.
Burada kullanıcı girişi ve Yetki Doğrulama hakkında daha fazla bilgi edinebilirsiniz.