PHP Tutorial Laravel 4 Framework (Authentication) - Recovering Forgotten Password I
Laravel 4
- Installing on Ubuntu - local
- Installing on a Shared host
- Installing on Windows
- Creating users table
- Home page with controller and blade
- Blade Templating
- Database connection and sending emails
- Creating user account I - GET
- Creating user account II - POST
- Creating user account III - Error checking & redirecting input
- Creating user account IV - User::create()
- Activating user account I - Mail::send()
- Activating user account II - Update user's status
- User account sign-in I - Route and link
- User account sign-in II - Validation
- User account sign-in III - Login Authentication
- Singing out
- Remember the user
- Changing Password I
- Changing Password II
- Recovering forgotten password I
- Recovering forgotten password II
- User Profile
- Database Migration using artisan
In this chapter, we'll work on how we can recover user's forgotten password.
We need a new menu for the forgotten password in views/layout/navigation.blade.php file like this
<nav> <ul> <li> <a href="{{ URL::route('home') }}">Home</a></li> @if(Auth::check()) <li><a href="{{ URL::route('account-sign-out') }}">Sign out</a></li> <li><a href="{{ URL::route('account-change-password') }}">Change password</a></li> @else <li><a href="{{ URL::route('account-sign-in') }}">Sign in</a></li> <li><a href="{{ URL::route('account-create') }}">Create an account</a></li> <li><a href="">Forgot password</a></li> @endif </ul> </nav>
Next, we're going to build the route for this.
Since the user forgot password, we should write a code in unauthenticated group:
/* Forgot password (GET) */ Route::get('/account/forgot-password', array('as' => 'account-forgot-password', 'uses' => 'AccountController@getForgotPassword' ));
views/account/forgot.blade.php:
@extends('layout.main') @section('content') Forgot password. @stop
public function getForgotPassword() { return View::make('account.forgot'); }
With the link to the page in navigation.php:
<li><a href="{{ URL::route('account-forgot-password') }}">Forgot password</a></li>
Let's see what we've got so far:
The click at the "Forgot password", we get the http://localhost/account/forgot-password with a plain text.
Now we want to work on POST route:
/* Forgot password (POST) */ Route::post('/account/forgot-password', array('as' => 'account-forgot-password-post', 'uses' => 'AccountController@postForgotPassword' ));
The POST method with validation looks like this:
public function postForgotPassword() { $validator = Validator::make(Input::all(), array( 'email' => 'required|email' ) ); if($validator->fails()) { return Redirect::route('account-forgot-password') ->withErrors($validator) ->withInput(); } else { } /* fall back */ return Redirect::route('account-forgot-password') ->with('global', 'Could not request new password.'); }
Put an error check:
@extends('layout.main') @section('content') <form action="{{ URL::route('account-forgot-password-post') }}" method="post"> <div class="field"> Email: <input type="text" name="email" value="{{ Input::old('email') }}"> @if($errors->has('email')) {{ $errors->first('email')}} @endif </div> <input type="submit" value="Recover"> {{ Form::token() }} </form> @stop
When we type wrong email address, the output looks like this:
But with the correct email, the picture below shows that it passed validation:
Here are the codes so far:
routes.php:
<?php Route::get('/', array('as' => 'home', 'uses' => 'HomeController@home' )); Route::get('/user/{username}', array('as' => 'profile-user', 'uses' => 'ProfileController@user' )); /* Authenticated group */ Route::group(array('before' => 'auth'), function() { /* CSRF protection */ Route::group(array('before' => 'csrf'), function() { /* Change password (POST) */ Route::post('/account/change-password', array('as' => 'account-change-password-post', 'uses' => 'AccountController@postChangePassword' )); }); // Change password (GET) Route::get('/account/change-password', array('as' => 'account-change-password', 'uses' => 'AccountController@getChangePassword' )); // Sign out (GET) Route::get('/account/sign-out', array('as' => 'account-sign-out', 'uses' => 'AccountController@getSignOut' )); }); /* Unauthenticated group */ Route::group(array('before' => 'guest'), function() { /* CSRF protection */ Route::group(array('before' => 'csrf'), function() { /* Create an account (POST) */ Route::post('/account/create', array('as' => 'account-create-post', 'uses' => 'AccountController@postCreate' )); /* Sign in (POST) */ Route::post('/account/sign-in', array('as' => 'account-sign-in-post', 'uses' => 'AccountController@postSignIn' )); /* Forgot password (POST) */ Route::post('/account/forgot-password', array('as' => 'account-forgot-password-post', 'uses' => 'AccountController@postForgotPassword' )); }); /* Forgot password (GET) */ Route::get('/account/forgot-password', array('as' => 'account-forgot-password', 'uses' => 'AccountController@getForgotPassword' )); /* Sign in (GET) */ Route::get('/account/sign-in', array('as' => 'account-sign-in', 'uses' => 'AccountController@getSignIn' )); /* Create an account (GET) */ Route::get('/account/create', array('as' => 'account-create', 'uses' => 'AccountController@getCreate' )); /* Activate an account */ Route::get('/account/activate/{code}', array('as' => 'account-activate', 'uses' => 'AccountController@getActivate' )); });
forgot.blade.php:
@extends('layout.main') @section('content') <form action="{{ URL::route('account-forgot-password-post') }}" method="post"> <div class="field"> Email: <input type="text" name="email" value="{{ Input::old('email') }}"> @if($errors->has('email')) {{ $errors->first('email')}} @endif </div> <input type="submit" value="Recover"> {{ Form::token() }} </form> @stop
navigation.blade.php:
<nav> <ul> <li> <a href="{{ URL::route('home') }}">Home</a></li> @if(Auth::check()) <li><a href="{{ URL::route('account-sign-out') }}">Sign out</a></li> <li><a href="{{ URL::route('account-change-password') }}">Change password</a></li> @else <li><a href="{{ URL::route('account-sign-in') }}">Sign in</a></li> <li><a href="{{ URL::route('account-create') }}">Create an account</a></li> <li><a href="{{ URL::route('account-forgot-password') }}">Forgot password</a></li> @endif </ul> </nav>
AccountController.php:
<?php class AccountController extends BaseController { /* Viewing the sign-in form */ public function getSignIn() { return View::make('account.signin'); } /* After submitting the sign-in form */ public function postSignIn() { $validator = Validator::make(Input::all(), array( 'email' => 'required|email', 'password' => 'required' ) ); if($validator->fails()) { // Redirect to the sign in page return Redirect::route('account-sign-in') ->withErrors($validator) ->withInput(); // redirect the input } else { $remember = (Input::has('remember')) ? true : false; $auth = Auth::attempt(array( 'email' => Input::get('email'), 'password' => Input::get('password'), 'active' => 1 ), $remember); } if($auth) { // Redirect to the intented page // For example, a user will be redirected to '/ // when the user tried to change password without login' return Redirect::intended('/'); } else { return Redirect::route('account-sign-in') ->with('global', 'Wrong Email/password wrong.'); } return Redirect::route('account-sign-in') ->with('global', 'There is a problem. Have you activated your account?'); } public function getSignOut() { Auth::logout(); return Redirect::route('home'); } /* Viewing the form */ public function getCreate() { return View::make('account.create'); } /* Submitting the form */ public function postCreate() { $validator = Validator::make(Input::all(), array( 'email' => 'required|max:50|email|unique:users', 'username' => 'required|max:20|min:3|unique:users', 'password' => 'required|min:6', 'password_again'=> 'required|same:password' ) ); if($validator->fails()) { return Redirect::route('account-create') ->withErrors($validator) ->withInput(); // fills the field with the old inputs what were correct } else { // create an account $email = Input::get('email'); $username = Input::get('username'); $password = Input::get('password'); // Activation code $code = str_random(60); /* This does the same as User::create() $user = new User; $user->fill(array( 'email' => $email, 'username' => $username, 'password' => Hash::make($password), 'code' => $code, 'active' => 0, )); $userdata = $user->save(); */ // record $userdata = User::create(array( 'email' => $email, 'username' => $username, 'password' => Hash::make($password), 'code' => $code, 'active' => 0 )); if($userdata) { Mail::send('emails.auth.activate', array('link' => URL::route('account-activate', $code), 'username' => $username), function($message) use ($userdata) { $message->to($userdata->email, $userdata->username)->subject('Activate your account'); }); return Redirect::route('home') ->with('global', 'Your account has been created. We have sent you an email to activate your accout'); } } } public function getActivate($code) { $user = User::where('code', '=', $code)->where('active', '=', 0); /* if user is available */ if($user->count()) { $user = $user->first(); // Update the user status to active $user->active = 1; $user->code = ''; if($user->save()) { return Redirect::route('home') ->with('global', 'Activated! You can now sign in!'); } } /* fall back */ return Redirect::route('home') ->with('global', 'We could not activate your account. Try again later.'); } public function getChangePassword() { return View::make('account.password'); } public function postChangePassword() { $validator = Validator::make(Input::all(), array( 'password' => 'required', 'old_password' => 'required|min:6', 'password_again'=> 'required|same:password' ) ); if($validator->fails()) { return Redirect::route('account-change-password') ->withErrors($validator); } else { // passed validation // Grab the current user $user = User::find(Auth::user()->id); // Get passwords from the user's input $old_password = Input::get('old_password'); $password = Input::get('password'); // test input password against the existing one if(Hash::check($old_password, $user->getAuthPassword())){ $user->password = Hash::make($password); // save the new password if($user->save()) { return Redirect::route('home') ->with('global', 'Your password has been changed.'); } } else { return Redirect::route('account-change-password') ->with('global', 'Your old password is incorrect.'); } } /* fall back */ return Redirect::route('account-change-password') ->with('global', 'Your password could not be changed.'); } public function getForgotPassword() { return View::make('account.forgot'); } public function postForgotPassword() { $validator = Validator::make(Input::all(), array( 'email' => 'required|email' ) ); if($validator->fails()) { return Redirect::route('account-forgot-password') ->withErrors($validator) ->withInput(); } else { } /* fall back */ return Redirect::route('account-forgot-password') ->with('global', 'Could not request new password.'); } }
Laravel 4
- Installing on Ubuntu - local
- Installing on a Shared host
- Installing on Windows
- Creating users table
- Home page with controller and blade
- Blade Templating
- Database connection and sending emails
- Creating user account I - GET
- Creating user account II - POST
- Creating user account III - Error checking & redirecting input
- Creating user account IV - User::create()
- Activating user account I - Mail::send()
- Activating user account II - Update user's status
- User account sign-in I - Route and link
- User account sign-in II - Validation
- User account sign-in III - Login Authentication
- Singing out
- Remember the user
- Changing Password I
- Changing Password II
- Recovering forgotten password I
- Recovering forgotten password II
- User Profile
- Database Migration using artisan
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization