Laravel Framework ile Rest Api Kullanımı(Bölüm-4)
Merhabalar Bölüm-1 , Bölüm-2 ve Bölüm-3 yazılarımda Laravel Framework ,Rest Api , Register ,Queue,Redis, Email Verify ,Notification,Login konularına değinmiştim,
Bu bölüm de ise kullanıcıların şifre yenileme işlemlerini anlatıyor olacağım. Şifre yenileme işlemi yaparken uygulamalar genellikle bizden mail adresimizi istiyor ve sistemde kayıtlı ise kullanıcıya şifre yenileme linki gönderiliyor.Sistemde kayıtlı değil ise kullanıcıya uyarı mesajı gösteriliyor.Gönderilen bu şifre yenileme maili için kullanıcı güvenliği için token oluşturulma işlemi yapılıyor.Ben de burada kullanılan sistemlere benzer bir yapı kurarak şifre yenileme işlemini anlatmış olacağım.
php artisan make:model ResetPassword -mcr
database/migrations/xxxx_create_password_resets_table.php dosyasında aşağıda ki kolonları ekliyoruz.
<?phpuse Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;class CreatePasswordResetsTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up() {
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}/**
* Reverse the migrations.
*
* @return void
*/
public function down() {
Schema::dropIfExists('password_resets');
}
}
ve ardından veritabanına eklemek için migrate komutunu çalıştırıyoruz.
php artisan migrate
ResetPassword modelimizi aşağıda ki gibi güncelliyoruz. Burada primaryKey olarak email kolonu belirtiyoruz. Her bir şifre yenileme için veritabanına kayıt yapıp silmek için ayrıca yeniden email gönderme işlemi yaptığında var olan email’e ait token bilgisini güvenlik dolayısıyla değiştirmek için daha sonra bu dosyamızı şifre değiştirme işlemi yaptıktan sonra primaryKey’e ait bilgileri temizliyoruz. Burada farklı yapı kurulabilir sistem de şifre yenileme işlemlerine kayıt altında tutabilirsiniz.
<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class ResetPassword extends Model {
//
protected $table = 'password_resets';protected $primaryKey = 'email';public $timestamps = false;protected $fillable = [
'email', 'token',
];
}
Model dosyamızı da değiştirdikten sonra ben Control sınıfı içerisinde şifre yenilemek isteyen kullanıcıdan alacağım mail’i sistem de kontrol edilmesini kayıt varsa reset_password tablosuna mail ve oluşturulan token bilgilerini kayıt edip veya daha önceden sistemden istediği şifre yenileme bilgisi kayıt altında ise token bilgilerini yenileyip Laravel Notification ile kullanıcıya şifre yenileme linki göndereceğim.
php artisan make:notification ResetPasswordNotify
komutulu ile ResetPasswordNotify sınıfımızı oluşturuyor ve içerisinde aşağıda ki değişiklikleri yapıyoruz
<?phpnamespace App\Notifications;use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ResetPasswordNotify extends Notification {
use Queueable;protected $token;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($token) {
$this->token = $token;
}/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable) {
return ['mail'];
}/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable) {
$url = url('/api/password/find/' . $this->token);return (new MailMessage)
->line('Şifrenizi Yenilemek İçin Butona Tıklayın')
->action('Değiştirme Linki', url($url))
->line('Uygulamamızı Kullandığınız İçin Teşekkür Ederiz!');
}/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable) {
return [
//
];
}
}
Değişiklerimiz’den sonra , mail tasarımında değişiklik(özelleştirme) yapmak istersek projemiz de default olarak bulunan mail şablonlarını Bölüm-2'de anlatmıştım o yapıyı yine burada kullanacağım.
Notification ayarlarımızı yaptıktan sonra kontrol sınıfımızda aşağıda ki değişiklikleri yapıyoruz.
<?phpnamespace App\Http\Controllers\Auth;use App\Http\Controllers\Controller;
use App\Notifications\ResetPasswordNotify;
use App\Notifications\ResetPasswordSuccess;
use App\ResetPassword;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;class ResetPasswordController extends Controller {
///**
* ResetPassword Token Store
*
* @param[string] email
* @return \Illuminate\Http\JsonResponse
*
*/
public function store(Request $request) {$rules = [
'email' => 'required|string|email|exists:users'
];$validator = Validator::make($request->all(), $rules);if ($validator->fails()) {$message['errors'] = $validator->errors();
return response()->json(['message' => $message, 'code' => 400]);
}$user = User::where('email', $request['email'])->first();if (!$user) {$message['error'] = 'Mail Adresi Bulunamadı';return response()->json(['message' => $message, 'code' => 404]);
}$resetpassword = ResetPassword::updateOrCreate(
[
'email' => $user->email,
],
[
'email' => $user->email,
'token' => str_random(45),
]
);if ($user && $resetpassword) {$user->notify(new ResetPasswordNotify($resetpassword->token));}$message['success'] = 'Email Şifre Yenileme Linki Gönderildi';return response()->json(['message' => $message, 'code' => 201]);
}/**
* Find Token
*
* @param[string] token
* @return \Illuminate\Http\JsonResponse
*
*/
public function find($token) {$resetpassword = ResetPassword::where('token', $token)->first();if (!$token) {$message['error'] = 'Token Geçersiz';return response()->json(['message' => $message, 'code' => 404]);
}if (Carbon::parse($resetpassword->created_at)->addMinutes(720)->isPast()) {$resetpassword->delete();
$message['error'] = 'Token Geçersiz';return response()->json(['message' => $message, 'code' => 404]);}$message['success'] = 'Başarılı';return response()->json(['resetpassword' => $resetpassword, 'code' => 200]);
}/**
* ResetPassword Token Store
*
* @param[string] email
* @param[string] password
* @param[string] token
* @return \Illuminate\Http\JsonResponse
*
*/
public function resetpassword(Request $request) {$rules = [
'email' => 'required|string|email|exists:users',
'token' => 'required|string',
'password' => 'required|string|min:6|confirmed',
];$validator = Validator::make($request->all(), $rules);if ($validator->fails()) {$message['errors'] = $validator->errors();
return response()->json(['message' => $message, 'code' => 400]);
}$resetpassword = ResetPassword::updateOrCreate(
[
'email' => $request->email,
'token' => $request->token,
]
)->first();if (!$resetpassword) {$message['error'] = 'Mail Adresi Bulunamadı';return response()->json(['message' => $message, 'code' => 404]);
}$user = User::where('email', $resetpassword->email)->first();if (!$user) {$message['error'] = 'Kullanıcı Bulunamadı';return response()->json(['message' => $message, 'code' => 404]);}$user->password = bcrypt($request->password);
$user->save();$resetpassword->delete();$user->notify(new ResetPasswordSuccess($resetpassword->token));$message['success'] = 'Kullanıcı Şifresi Başarıyla Değiştirildi.';return response()->json(['message' => $message, 'code' => 201]);
}
}
Control metotumuzu incelediğimiz de kullanıcıya gönderilen değiştirme linkinden sonra kullanıcının gördüğü mail,password bilgilerini yeniden isteyerek değişiklikeri başarıyla yapıyoruz ve resetpassword tablosundan kayıtı siliyoruz.
routes/api.php dosyamızı da güncelliyoruz;
<?phpuse Illuminate\Http\Request;/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});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('login/verify/{code?}', 'AuthController@loginVerify');
Route::get('email/resend/{email?}', 'AuthController@resend');Route::group(['middleware' => 'auth:api'], function () {Route::post('logout', 'AuthController@logout');
Route::get('users', 'AuthController@getAllUser')->middleware('verified');
Route::get('me', 'AuthController@me');
});});/*
Bu Grup tanımında ise password yenileme
*/Route::group([
'namespace' => 'Auth',
'prefix' => 'password',], function () {Route::post('sendtoken', 'ResetPasswordController@store');
Route::get('find/{token?}', 'ResetPasswordController@find');
Route::post('resetpassword','ResetPasswordController@resetpassword';});
Yapılan değişikliklerden sonra Postman üzerinden uygulamamızı test ediyoruz ,
Mailimize gelen bağlantı ;
resetpassword();
Succes Mail;
Bu yazı ile birlikte genel kullanıcı işlemlerini ve şifre yenileme yapılarını anlatmış oldum.Kullanıcı işlemlerini dair geliştirilebilecek birçok tasarım mevcut ben bu şekilde yapmış oldum. Auth yapılarında tabi ki kullanıcı rol yapıları mevcuttur bununla ilgili çalışmalarım ileri ki yazılarım da ele alacağım.Hata ve yanlışlarım da dönüş yaparsanız mutlu olurum. Bir sonra ki yazım da görüşmek üzere….
Önce ki yazılarım;
Bölüm-1;
Bölüm-2;
Bölüm-3;
Proje dosyamız github’da;
Postman üzerinde endpointler verilmiştir;