Laravel Framework ile Rest Api Kullanımı(Bölüm-2)
Merhabalar , Bölüm-1 yazımda Laravel Framework’ün temel bilgilerden bahsedip , Rest Api konusuna giriş yapmıştım,
Laravel Passport Paketini kurup Login ve Register olaylarını kısaca anlatmıştım.Bu yazımda yapıları biraz daha geliştirerek kullanıcı kayıt olduktan sonra kullanıcıya onay maili göndereceğiz,onaylanan mail’den sonra kullanıcıya hoşgeldin mesajı göndereceğiz. Şimdi sırasıyla yapmaya başlayalım;
İlk olarak User tablomuz’daki değişiklikleri yapıyoruz; database/migrations/xxxx_create_users_table.php dosyamız’a phonenumber,verified,active,token,avatar,email_verified_at,remember_token,softDeletes kolonlarını ekliyoruz.
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;class CreateUsersTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->string('phonenumber')->unique()->nullable();
$table->boolean('verified')->default(false);
$table->boolean('active')->default(false);
$table->string('token')->unique()->nullable();
$table->string('avatar')->default('avatar.png');
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->softDeletes();
$table->timestamps();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::dropIfExists('users');
}
}
App\User dosyamızı güncelliyoruz;
<?phpnamespace App;use App\Notifications\AccountVerify;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Passport\HasApiTokens;class User extends Authenticatable {use HasApiTokens, Notifiable, SoftDeletes;protected $dates = ['deleted_at'];/**
* Tablomuzdan Gösterilen
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password', 'phonenumber', 'token', 'active',
];/**
* Tablomuzdan Gizlenen
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];/**
* Email Onay Özelliği
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];}
Son olarak aşağıda ki komutları çalıştırıyoruz;
/* Veritabanında bulunan tabloları temizler ve migrations dosyalarını yeniden yükler*/
php artisan migrate:refresh/*Authentication Yapısı İçin Kullandığımız Passpor paketini tekrar aktif ediyoruz*/
php artisan passport:install
Veritabanı dosyamız ile Model dosyamızı güncelledik ve ilk aşamayı bitiriyoruz.
Yapı olarak kayıt işlemlerinden sonra kullanıcıya onay için mail gönderiyoruz ve onaylanan kullanıcıların sisteme giriş yapmasına izin veriyoruz demiştik ben işlem için Laravel Notification yapısını kullanarak mail gönderme işlemlerini gerçekleştiriyorum .
AccountVerify adında notification sınıfımızı oluşturuyoruz aşağıda ki komut ile birlikte;
php artisan make:notification AccountVerify
AccountVerify sınıfımıza VeriyEmail sınıfımızdan miras alıyoruz ve toMail ve verificationUrl metotlarımızı overload ederek aşağıda ki gibi değişiklik yapıyoruz;
<?phpnamespace App\Notifications;use Illuminate\Auth\Notifications\VerifyEmail as AccountVerifyBase;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\URL;/**
* Bu Kısımda AccountVerify adında bir notification sınıfı oluşturduk
* VerifyEmail Sınıfından Miras Aldık ve Overload Yaparak Kullanıcı Mail Özelleştirmelerini Yaptık
*
*/
class AccountVerify extends AccountVerifyBase {/**
* Build the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable) {
$verificationUrl = $this->verificationUrl($notifiable);return (new MailMessage)
->greeting(Lang::getFromJson('Merhaba'))
->subject(Lang::getFromJson('E-Posta Doğrulayın'))
->line(Lang::getFromJson('E-posta adresinizi doğrulamak için lütfen aşağıdaki linke tıklayın.'))
->action(Lang::getFromJson('E-posta Doğrulayın'), $verificationUrl);
}/**
* Get The verification URL for
*
* @param mixed $notifiable
*
*/
protected function verificationUrl($notifiable) {
return URL::temporarySignedRoute('verification.verify',
Carbon::now()->addMinutes(60), ['token' => $notifiable->token]
);
}
}
Değişiklerimiz’den sonra , mail tasarımında değişiklik(özelleştirme) yapmak istersek projemiz de default olarak bulunan mail şablonlarını ;
php artisan vendor:publish --tag=laravel-notifications
komutu ile mail dosyalarını public/resources/views ( vendor/mail and vendor/notification) klasörümüzün altına alıyoruz. Ayrıca , config/mail.php dosyamızın içerisinden dosya yolunu ve mail temasını değiştirebilirsiniz.
'markdown' => [
'theme' => 'default','paths' => [
resource_path('views/vendor/mail'),
],
],
Bildirim ayarlarını bitirdik, mail dosyalarımızı özelleştirdik , mail ayarlamaları için .env klasöründen sunucunuza göre gerekli ayarlarınızı yapabilirsiniz;
MAIL_DRIVER=smtp
MAIL_HOST= Mail sunucunuzu
MAIL_PORT= Portunuzu
MAIL_USERNAME= Kullanıcı Adınızı
MAIL_PASSWORD= Parola
MAIL_ENCRYPTION=ssl
Notification ayarlarını yaptıktan sonra app\User modelimizi yeniden güncelliyoruz sendApiConfirmAccount() fonksiyonunu ekliyoruz ;
/* Tanımlamasını Yapıyoruz*/
use App\Notifications\AccountVerify;/**
*
* Kullanıcı Doğrulama İçin Çalışan Metot
*
*/
public function sendApiConfirmAccount() {
$this->notify(new AccountVerify);
}
Kullanıcı mail onay bağlantısına tıkladıktan sonra kullanıcıya Hoş Geldiniz mail’i göndermek için Laravel Mail sınıfını kullanıyorum ,aşağıdaki komutu çalıştırıyoruz ;
php artisan make:mail UserWelcome --markdown=emails.welcome
Komutu ile birlikte Mailable sınıfını extend alan App\Mail\UserWelcome sınıfını oluşturuyor ,--markdown=emails.welcome
komutu ile public/resources/views ( emails/welcome) mail dosyalarını hazırlıyoruz ben welcome.php üzerinde aşağıda ki gibi değişiklik yapıyorum,
@component('mail::message')
# Hoşgeldiniz{{$name}}Teşekkür Ederiz,<br>
{{ config('app.name') }}
@endcomponent
App\Mail\UserWelcome sınıfının son hali;
<?phpnamespace App\Mail;use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;class UserWelcome extends Mailable {
use Queueable, SerializesModels;protected $name;
protected $email;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
}/**
* Build the message.
*
* @return $this
*/
public function build() {
return $this
->subject('Aramıza Hoşgeldin!')
->to($this->email)
->with(['name' => $this->name])
->markdown('emails.welcome');
}
}
Değişikliklerimiz’den sonra api.php dosyamızı düzenliyoruz;
Route::group([
'namespace' => 'Auth',
'prefix' => 'auth',], function () {Route::post('register', 'AuthController@register');
Route::post('login', 'AuthController@login');
Route::get('email/verify/{token}', 'AuthController@verify')->name('verification.verify');});
Ve Son olarak AuthController dosyamızda register() metotu değiştiriyoruz ve verify() metotunu sınıfımıza dahil ediyoruz;
<?phpnamespace App\Http\Controllers\Auth;use App\Http\Controllers\Controller;
use App\SmsVerification;
use App\User;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Mail;class AuthController extends Controller {use VerifiesEmails;/**
* Kullanıcı Kayıt İşlemleri
*
* @param[string] name
* @param[string] email
* @param[string] password
* @return \Illuminate\Http\JsonResponse
*
*/
public function register(Request $request) {$rules = [
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string|min:6|confirmed',
'phonenumber' => 'required|string|min:10|unique:users',
];$validator = Validator::make($request->all(), $rules);if ($validator->fails()) {
return response()->json(['message' => $validator->errors(), 'code'=>400]);
}$user = new User([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password),
'token' => str_random(60),
'phonenumber' => $request->phonenumber,
]);$user->save();/*User modelimizde oluşturduğumuz fonksiyonumuzu çağırıyoruz ve Kullanıcıya Mail Onayı İçin Mail Gönderiyoruz*/
$user->sendApiConfirmAccount();$message['success'] = 'Kullanıcı Başarıyla Oluşturuldu Sisteme Giriş İçin Mailinizi Kontrol Ediniz.';return response()->json(['message' => $message, 'code' => 201]);
}/**
* Kullanıcı Email Onaylama
*
*
* @return \Illuminate\Http\JsonResponse
*/
protected function verify(Request $request) {$user = User::where('token', $request['token'])->firstOrFail();if ($user->hasVerifiedEmail()) {$message['error'] = 'Daha Önceden Email Doğrulandı';return response()->json(['message' => $message, 'code' => 422]);
}$user->email_verified_at = now();$user->active = true;$user->token = null;$user->save();/*
$setDelay = Carbon::parse($user->email_verified_at)->addSeconds(10);
Bu kısımda isterseniz Kullanıcıya Hoşgeldinizi Maili İçin Gecikme Verebilirsiniz.
Mail::queue(new \App\Mail\UserWelcome($user->name, $user->email))->delay($setDelay);
*/Mail::queue(new \App\Mail\UserWelcome($user->name, $user->email));$message['success'] = 'Kullanıcı Email Doğrulandı';return response()->json(['message' => $message, 'code' => 200]);
}}
Buraya kadar olan kısımda kullanıcı kayıt, mail gönderme ve onaylama işlemlerini yaptık. Her kullanıcı için mail onay bağlantısı ve hoşgeldin maili gönderme işlemi sistemi yavaşlatacak ve gecikmelere neden olacaktır.Bu problemi çözmek için Laravel Queues (Kuyruklama) kullanacağız. Kuyruklama mantığı ile gönderilecek mailleri sıraya alarak oluşabilecek hata ve sistemin yavaşlamasını engelliyoruz. Kuyruklama sistemi için Redis,Beanstalk,Amazon SQS vb yapılar kullanabiliyoruz ben burada Redis kullanacağım ve local’de Redis kurulumu için bağlantıyı inceleyebilirsiniz;
Aşağıda ki komut ile projemize redis’i dahil ediyoruz;
composer require predis/predis
komutu ile projemize dahil ediyoruz ve .env klasörümüzde Redis’i yapılandıralım.
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=7777
Kuyruklama için kullanacağım yapı Redis olduğu için .env klasörümüzde ki bağlantıyı tanımlıyoruz;
QUEUE_CONNECTION=redis
Son olarak Laravel Framework’de kuyruklama işleminin çalışması için dinlemeniz gerekiyor ;
php artisan queue:listen
ile dinliyoruz sonra projemiz test için ; Postman üzerinden kullanıcı kayıt işlemini gerçekleştiriyoruz;
Mailimizi kontrol edelim;
E-posta doğrula dedikten sonra karşımıza gelen başarılı mesajından sonra , kullanıcıya yine hoş geldin maili gönderiyoruz
Tekrar edecek olursak kullanıcıdan sisteme kayıt için gerekli alanları istiyoruz ve bu alanları Validate kontrolü yapıp doğru ise kayıt işlemini gerçekleştiriyor ve kullanıcı onaylamak için mail gönderiyoruz. Gelen mail’de ki bağlantıya tıkladığı zaman kullanıcı sisteme kayıt oluyor ve Kullanıcıya hoşgeldin maili gönderiyoruz.
Sistemde sorunumuz oldu kullanıcıya doğrulama bağlantısı gitmedi tekrar bağlantı göndermek istersek;
routes\api.php dosyamızda aşağıda ki gibi değişiklik yapıyoruz ;
Route::group([
'namespace' => 'Auth',
'prefix' => 'auth',], function () {Route::post('register', 'AuthController@register');
Route::post('login', 'AuthController@login');
Route::get('email/verify/{token}', 'AuthController@verify')->name('verification.verify');
Route::get('email/resend/{email}', 'AuthController@resend');});
Daha sonra AuthController sınıfımıza resend metotumuzu ekliyoruz;
/**
* Yeniden Mail Gönderme İşlemi
*
*
* @return \Illuminate\Http\JsonResponse
*/
protected function resend(Request $request) {$rules = [
'email' => 'required|string|email|unique:users'
];$validator = Validator::make($request->all(), $rules);if ($validator->fails()) {
return response()->json(['message' => $validator->errors(), 'code' => 400]);
}$user = User::where('email', $request['email'])->first();if ($user->hasVerifiedEmail()) {$message['info'] = 'Daha Önceden Email Doğrulandı';return response()->json(['message' => $message, 'code' => 422]);}$user->sendApiConfirmAccount();$message['info'] = 'Yeniden Mail Gönderildi';return response()->json(['message' => $message, 'code' => 200]);}
Yeniden gönderilecek onay bağlantısı için kullanıcıdan alınan mail’in kontrolünü sağlayıp bağlantıyı gönderiyoruz.
Kullanıcı kayıt operasyonları için yapılacak kısımları burada bitiyoruz. Hatalı veya eksik gördüğünüz kısımlarda bana dönüş sağlarsanız sevinirim.
Bölüm-1;
Bölüm-3;
Bölüm-4 ;
Proje dosyamız github’da;
Postman üzerinde endpointler verilmiştir;