Neler yeni

Laravel'de Özel Şifremi Unuttum ve Parola Sıfırlama Fonksiyonu

netr0n

Active member
Yönetici
Administrator
Katılım
17 Eki 2016
Mesajlar
580
Tepkime puanı
39
Puanları
28
Laravel'de jetstream kullanmak istemiyorsak, kendi şifremi unuttum ve parola sıfırlama işlemlerimizi özel olarak oluşturabiliriz.

Not: Ben Türkçe olarak tablolarımı oluşturdum. Eğer sizde Türkçe olarak oluşturacaksanız model dosyanızda işlem yapmayı unutmayın.


Benim giris.blade.php giriş (login) alanımın kodları şu şekilde ;

HTML:
<section class="login_area section--padding2">
    <div class="container">
        <div class="row">
            <div class="col-lg-6 offset-lg-3">
                <form action="{{ route('giris') }}" method="POST">
                    @csrf
                    <div class="cardify login">
                        <div class="login--header">
                            <h3>Hoş Geldiniz.</h3>
                            <p>e-Posta hesabınızla giriş yapabilirsiniz</p>
                        </div>
                        <div class="login--form">
                            <div class="form-group">
                                <label for="email">e-Posta</label>
                                <input id="email" type="email" name="email" class="text_field" placeholder="e-Posta adresinizi giriniz...">
                                @error('email')
                                <span class="help-block">
                                    <strong>{{ $message }}</strong>
                                </span>
                                @enderror
                            </div>
                            <div class="form-group">
                                <label for="sifre">Şifre</label>
                                <input id="sifre" type="password" name="sifre" class="text_field" placeholder="Şifrenizi giriniz...">
                            </div>
                            <div class="form-group">
                                <div class="custom_checkbox">
                                    <input type="checkbox" id="ch2" name="benihatirla" checked>
                                    <label for="ch2">
                                        <span class="shadow_checkbox"></span>
                                        <span class="label_text">Beni hatırla</span>
                                    </label>
                                </div>
                            </div>
                            <button class="btn btn--md btn--round" type="submit">Giriş Yap</button>
                            <div class="login_assist">
                                <p class="recover">
                                    <a href="/forget-password">Şifremi Unuttum?</a>
                                <p class="signup">Hesap oluşturmak için
                                    <a href="{{ route('kaydol') }}">Kayıt Ol</a>?</p>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</section>


İlk olarak resources/views dizini içerisinde customauth adında bir dizin oluşturuyoruz ve bu dizinin içerisinde passwords adında bir dizin daha oluşturalım. Bu dizinin içerisinde email.blade.php dosyamızı oluşturalım. Bu dosyamızın kodları aşağıdaki gibi oluşturuldu.

HTML:
@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Confirm Password') }}</div>

                <div class="card-body">
                    {{ __('Please confirm your password before continuing.') }}

                    <form method="POST" action="{{ route('password.confirm') }}">
                        @csrf

                        <div class="row mb-3">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Confirm Password') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Şimdi web.php dosyamıza aşağıdaki routerlarımızı ekleyelim.

PHP:
Route::get('/forget-password', [ForgotPasswordController::class, 'getEmail']);
Route::post('/forget-password', [ForgotPasswordController::class, 'postEmail']);

Artık tablomuzu oluşturabiliriz. Bunun için ben aşağıdaki gibi bir tablo oluşturdum.

Kod:
php artisan make:migration create_sifre_sifirlama_mail_table

Bu oluşturmuş olduğum tablonun içeriği aşağıdaki gibidir.

PHP:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateSifreSifirlamaMailTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('sifre_sifirlama_mail', 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('sifre_sifirlama_mail');
    }
}

Şimdi tablomuzu migrate edelim.

Kod:
php artisan migrate

Şimdi ForgotPasswordController oluşturmamız gerekiyor. Aşağıdaki komut ile controller dosyamızı oluşturuyoruz.

Kod:
php artisan make:controller ForgotPasswordController

Bu controller dosyamızın kodları aşağıdaki gibidir.

PHP:
<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Carbon\Carbon;
use Illuminate\Support\Str;

class ForgotPasswordController extends Controller
{
    public function getEmail()
    {

        return view('customauth.passwords.email');
    }

    public function postEmail(Request $request)
    {
        $request->validate([
            'email' => 'required|email|exists:kullanici',
        ]);

        $token = Str::random(64);

        DB::table('sifre_sifirlama_mail')->insert(
            ['email' => $request->email, 'token' => $token, 'created_at' => Carbon::now()]
        );

        Mail::send('customauth.verify', ['token' => $token], function($message) use($request){
            $message->to($request->email);
            $message->subject('Paralo sıfırlama bildirimi');
        });

        return back()->with('message', 'Şifre sıfırlama bağlantınızı e-posta ile gönderdik!');
    }
}

Burada .env dosyanıza mail ayrıntılarınızı girebilirsiniz. Test etmek için mailtrap kullanabilirsiniz.

Devam ediyoruz...

Şimdi mail doğrulama şablonumuzu oluşturabiliriz. Bunun için resources/views/customauth dizini içerisinde verify.blade.php adında bir dosya oluşturuyoruz ve örnek şablonumuz aşağıdaki gibidir.

HTML:
<!doctype html>
<html lang="tr">
    <head>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
        <title>Şifre Sıfırlama Maili</title>
        <meta name="description" content="Şifre Sıfırlama">
        <style type="text/css">
            a:hover {text-decoration: underline !important;}
        </style>
    </head>

    <body marginheight="0" topmargin="0" marginwidth="0" style="margin: 0px; background-color: #f2f3f8;" leftmargin="0">
        <table cellspacing="0" border="0" cellpadding="0" width="100%" bgcolor="#f2f3f8"
               style="@import url(https://fonts.googleapis.com/css?family=Rubik:300,400,500,700|Open+Sans:300,400,600,700); font-family: 'Open Sans', sans-serif;">
            <tr>
                <td>
                    <table style="background-color: #f2f3f8; max-width:670px;  margin:0 auto;" width="100%" border="0"
                           align="center" cellpadding="0" cellspacing="0">
                        <tr>
                            <td style="height:80px;">&nbsp;</td>
                        </tr>
                        <tr>
                            <td style="text-align:center;">
                                <a href="#sitelink" title="logo" target="_blank">
                                    <img width="60" src="#siteLogo" title="logo" alt="logo">
                                </a>
                            </td>
                        </tr>
                        <tr>
                            <td style="height:20px;">&nbsp;</td>
                        </tr>
                        <tr>
                            <td>
                                <table width="95%" border="0" align="center" cellpadding="0" cellspacing="0"
                                       style="max-width:670px;background:#fff; border-radius:3px; text-align:center;-webkit-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);-moz-box-shadow:0 6px 18px 0 rgba(0,0,0,.06);box-shadow:0 6px 18px 0 rgba(0,0,0,.06);">
                                    <tr>
                                        <td style="height:40px;">&nbsp;</td>
                                    </tr>
                                    <tr>
                                        <td style="padding:0 35px;">
                                            <h1 style="color:#1e1e2d; font-weight:500; margin:0;font-size:32px;font-family:'Rubik',sans-serif;">Şifre Sıfırla Maili</h1>
                                            <span
                                                  style="display:inline-block; vertical-align:middle; margin:29px 0 26px; border-bottom:1px solid #cecece; width:100px;"></span>
                                            <p style="color:#455056; font-size:15px;line-height:24px; margin:0;">
                                                Size eski şifrenizi gönderemeyiz. Size şifrenizi sıfırlamanız için benzersiz bir bağlantı oluşturuldu. Şifrenizi sıfırlamak için aşağıdaki bağlantıya tıklayın ve talimatları izleyin.
                                            </p>
                                            <a href="http://127.0.0.1:8000/reset-password/{{$token}}"
                                               style="background:#20e277;text-decoration:none !important; font-weight:500; margin-top:35px; color:#fff;text-transform:uppercase; font-size:14px;padding:10px 24px;display:inline-block;border-radius:50px;">Şifremi Sıfırla</a>
                                        </td>
                                    </tr>
                                    <tr>
                                        <td style="height:40px;">&nbsp;</td>
                                    </tr>
                                </table>
                            </td>
                        <tr>
                            <td style="height:20px;">&nbsp;</td>
                        </tr>
                        <tr>
                            <td style="text-align:center;">
                                <p style="font-size:14px; color:rgba(69, 80, 86, 0.7411764705882353); line-height:18px; margin:0 0 0;">&copy; <strong>www.netron.web.tr</strong></p>
                            </td>
                        </tr>
                        <tr>
                            <td style="height:80px;">&nbsp;</td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </body>
</html>

Evet şifremi unuttum bağlantınıza tıkladığınızda sizi mail doğrulama alanına yönlendirip yönlendirmediğini bu durumda kontrol edebilirsiniz. Her şey yolunda ise web.php üzerinde sıfırlama routerlarımızı oluşturalım.

PHP:
Route::get('/reset-password/{token}', 'ResetPasswordController@getPassword');
Route::post('/reset-password', 'ResetPasswordController@updatePassword');

Şimdi şifre sıfırlama controller dosyamızı oluşturalım. Aşağıdaki komutu çalıştıralım;

Kod:
php artisan make:controller ResetPasswordController

Kod içeriğimiz aşağıdaki gibidir.

PHP:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use App\Models\Kullanici;

class ResetPasswordController extends Controller
{
    public function getPassword($token) {

            return view('customauth.passwords.reset', ['token' => $token]);
     }

     public function updatePassword(Request $request)
    {

            $request->validate([
                'email' => 'required|email|exists:kullanici',
                'sifre' => 'required|string|min:6|confirmed',
                'sifre_confirmation' => 'required',

            ]);

            $updatePassword = DB::table('sifre_sifirlama_mail')
            ->where(['email' => $request->email, 'token' => $request->token])
            ->first();

            if(!$updatePassword)
            return back()->withInput()->with('error', 'Geçersiz token!');

            $user = Kullanici::where('email', $request->email)
            ->update(['sifre' => Hash::make($request->sifre)]);

            DB::table('sifre_sifirlama_mail')->where(['email'=> $request->email])->delete();

            return redirect('/giris')->with('message', 'Şifreniz değiştirildi!');

        }

}

Şimdi reset şablonumuzu oluşturalım. Yine resources/views/customauth dizini içerisinde reset.blade.php dosyamızı oluşturalım. Şablon içeriği aşağıdaki gibidir.

HTML:
<section class="login_area section--padding2">
        <div class="container">
            <div class="row">
                <div class="col-lg-6 offset-lg-3">
                    <form action="/reset-password" method="POST">
                        @csrf
                        <input type="hidden" name="token" value="{{ $token }}">
                        <div class="cardify login">
                            <div class="login--header">
                                <h3>Şifre Sıfırlama Formu</h3>
                                <p>Lütfen Yeni Şifrenizi Giriniz</p>
                            </div>

                            <div class="login--form">
                            <div class="form-group">
                                    <label for="email">e-Posta</label>
                                    <input id="email" type="email" name="email" class="text_field" placeholder="e-Posta adresiniz" @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}">
                                    @error('email')
                                    <span class="help-block">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                    @enderror
                                </div>
                                <div class="form-group">
                                    <label for="sifre">Yeni Şifreniz</label>
                                    <input id="sifre" type="password" name="sifre" class="text_field" placeholder="Şifrenizi giriniz..." @error('password') is-invalid @enderror">
                                </div>
                                <div class="form-group">
                                    <label for="sifre_confirm">Şifre (Tekrar)</label>
                                    <input id="sifre_confirm" type="password" name="sifre_confirmation" class="text_field" placeholder="Şifrenizi giriniz...">
                                </div>
                                <button class="btn btn--md btn--round" type="submit">Güncelle</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </section>

Evet işlemlerimiz buraya kadar. Şifre sıfırlama ve şifremi unuttum alanını özel olarak oluşturmuş olduk.
 
Üst