Laravel dan Android Tutorial

Blogger news

Email Aktifasi/Verifikasi dengan Laravel 5.3

4 komentar
Pada saat mendaftar sebuah layanan website, biasanya akan dikirim email untuk aktifasi/verifikasi dari email yang digunakan pada saat mendaftar tersebut. ya tergantung sih, ada atau tidak. tapi, jika ingin membuat user registration dengan email aktifasi/verifikasi pada Laravel, bisa mengikuti tutorial berikut ini.


dalam kasus ini, user meskipun sudah mendaftar tapi belum aktifasi/verifikasi emailnya tidak dapat masuk ke sistem. tapi tentu ya bisa diubah-ubah sendiri nantinya.

pertama siapkan database, ada dua tabel yaitu User dan UserActivation. tabel User sudah ada secara default pada Laravel. untuk itu buat tabel User Activation dahulu.

php artisan make:migration create_user_activations_table --create=user_activations

struktur dari tabel user_activations seperti berikut.

 
untuk tabel user tambahkan kolom baru untuk menandai apakah email user sudah di aktifasi/verifikasi apa belum.


untuk tabel selesai lanjutkan dengan migrate database.

php artisan migrate

persiapan untuk database selesai, lanjut untuk pembuatan kode aktifasi/verifikasi dengan token. tapi sebelumnya jangan lupa jalankan artisan command make:auth untuk membuat user registration.

php artisan make:auth

buat file baru di folder app. beri nama ActivationRepository.php
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Connection;
class ActivationRepository{
protected $db;
protected $table = "user_activations";
public function __construct(Connection $db){
$this->db = $db;
}
protected function getToken(){
return hash_hmac('sha256', str_random(40), config('app.key'));
}
public function createActivation($user){
$activation = $this->getActivation($user);
if(!$activation){
return $this->createToken($user);
}
return $this->regenerateToken($user);
}
private function regenerateToken($user){
$token = $this->getToken();
$this->db->table($this->table)->where('user_id', $user->id)->update([
'token' => $token,
'created_at' => new Carbon()
]);
return $token;
}
private function createToken($user){
$token = $this->getToken();
$this->db->table($this->table)->insert([
'user_id' => $user->id,
'token' => $token,
'created_at' => new Carbon()
]);
return $token;
}
public function getActivation($user){
return $this->db->table($this->table)->where('user_id', $user->id)->first();
}
public function getActivationByToken($token){
return $this->db->table($this->table)->where('token', $token)->first();
}
public function deleteActivation($token){
return $this->db->table($this->table)->where('token', $token)->delete();
}
}
emailnya berbentuk notifikasi, jadi buat notifikasi dahulu.

php artisan make:notification ConfirmUserEmail

file notifikasi berada di app/Notifications. atur ConfirmUserEmail seperti berikut
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class ConfirmUserEmail extends Notification
{
use Queueable;
public $token;
public function __construct($token){
$this->token = $token;
}
public function via($notifiable){
return ['mail'];
}
public function toMail($notifiable){
return (new MailMessage)
->success()
->line('Almost Done!')
->line('Click Button Below to Verify Your Email Address')
->action('Activate Your Account', route('user.activate', $this->token));
}
public function toArray($notifiable)
{
return [
//
];
}
}
buat file baru lagi, di folder app untuk menangani pengiriman email aktifasi/ verifikasi. beri nama ActivationService.php.
<?php
namespace App;
use App\Notifications\ConfirmUserEmail;
class ActivationService{
protected $activationRepo;
protected $resendAfter = 24;
public function __construct(ActivationRepository $activationRepo){
$this->activationRepo = $activationRepo;
}
public function sendActivationMail($user){
if($user->activated || !$this->shouldSend($user)){
return;
}
$token = $this->activationRepo->createActivation($user);
$user->notify(new ConfirmUserEmail($token));
}
public function activateUser($token){
$activation = $this->activationRepo->getActivationByToken($token);
if($activation === null){
return null;
}
$user = User::find($activation->user_id);
$user->activated = true;
$user->save();
$this->activationRepo->deleteActivation($token);
return $user;
}
private function shouldSend($user){
$activation = $this->activationRepo->getActivation($user);
return $activation === null || strtotime($activation->created_at) + 60 * 60 * $this->resendAfter < time();
}
}
sekarang siap digunakan pada Controller. dipakai di RegisterController dan LoginController.
pada RegisterController ubah dan tambahkan function baru register dan activateUser seperti berikut.
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use App\ActivationService;
class RegisterController extends Controller{
use RegistersUsers;
protected $redirectTo = '/home';
protected $activationService;
public function __construct(ActivationService $activationService){
$this->middleware('guest');
$this->activationService = $activationService;
}
protected function validator(array $data){
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
protected function create(array $data){
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
public function register(Request $request){
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$user = $this->create($request->all());
$this->activationService->sendActivationMail($user);
return redirect('/login')->with('status', 'We sent you an activation code. Check your email.');
}
public function activateUser($token){
if ($user = $this->activationService->activateUser($token)) {
auth()->login($user);
return redirect($this->redirectPath());
}
abort(404);
}
}
pada LoginController ubah dan tambahkan function authenticated seperti berikut.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use App\ActivationService;
class LoginController extends Controller{
use AuthenticatesUsers;
protected $redirectTo = '/home';
public function __construct(ActivationService $activationService)
{
$this->middleware('guest', ['except' => 'logout']);
$this->activationService = $activationService;
}
public function authenticated(Request $request, $user){
if (!$user->activated) {
$this->activationService->sendActivationMail($user);
auth()->logout();
return back()->with('warning', 'You need to confirm your account. We have sent you an activation code, please check your email.');
}
return redirect()->intended($this->redirectPath());
}
}
dan jangan lupa route untuk aktifasi/verifikasi user.


terkahir untuk view login.blade.php tambahkan code untuk menampilkan status pada saat mendaftar.


tampilan emailnya seperti berikut (menggunakan mailtrap). atur emailnya di file .env


catatan:
untuk header email diambil dari nama aplikasi yang berada di config/app.php

download projectnya disini.
referensi

4 komentar :

  1. Mas ko saya malah nemu error "FatalThrowableError in RegisterController.php line 86: Call to a member function sendActivationMail() on null" padahal sudah saya ikutin langkah-langkahnya.

    BalasHapus
    Balasan
    1. udah di import use App\ActivationService di RegisterController? cek juga import di ActivationService. download sample projectnya kan, coba diperiksa.

      Hapus
  2. Komentar ini telah dihapus oleh pengarang.

    BalasHapus
  3. error tidak di temukan Method [throwValidationException] does not exist on [App\Http\Controllers\Auth\RegisterController]. ada solusi??

    BalasHapus