Access all tutorials in sprocket icon.
August 6, 2015 from author Bill Keck.
Update December 21, 2015 for Laravel 5.2
Just a quick note that Laravel 5.2 now features an artisan command:
php artisan make:auth
This will create the basic views you need for login, registration, and password resets.
You might still want to read through this tutorial, it will give you an idea on how the AuthController works, which is essential later on when you want to modify it. Also, I provide the routes that you will need and we cover the redirectTo property, which will you most likely need as well.
Here is the original tutorial:
User login and registration for laravel 5.1.4 tutorial
In this tutorial, we are going to build the basic user login and registration routes and views. We assume you have a fresh install of Laravel 5.1.4. If you need help setting that up, please reference my Laravel Installation tutorial or visit the laravel.com docs.
We also assume that you have setup your database and run the first migration. If not, please read my tutorial on Database Setup in Laravel 5.1.
Also note, we are going to use Gists, which are online code snippets hosted by Github, for the views, so this will make copy and pasting of the views very easy.
Before we begin, let’s talk about the difference between laravel 5.0 and 5.1 and 5.1.4.
Background
5.0 came with a working user registration and password implementation right out of the box. In some ways, it was very convenient because it gave you the routes, model, controllers, and views that you needed to have instant registration and login. In other ways, it was an awkward implementation. It used, for example, the following route declaration:
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
In this way of doing routing, the verbs on the controller define the type of route, for example:
public function getRegister()
So if you typed in a url such as yourdomain.com/auth/register, it would send you to the getRegister method on the controller. This is perhaps one of the less intuitive and more complicated ways of doing this.
To complicate things even further, the AuthController used a trait to pull in the getRegister method, so that was not even visible directly in the controller.
Taylor Otwell has made an artform out of making things simpler, and this just seemed way overly-complicated.
So when 5.1 released, I expected things to get simpler, and they did to some extent, but they also got a little stranger.
The AuthController was still using traits, but dropped the registrar class, which had formerly created the user, in favor of a more direct approach. That made it a little simpler.
At the same time, none of the routes or the views for login and registration, which came ready-made out of the box in 5.0 were included in 5.1. So unless you were simply upgrading from 5.0 to 5.1, you had to build all that from scratch.
So I wrote this tutorial for 5.1 and eliminated the main trait to make it easier to work with, but then guess what? Within 2 months 5.1.4 was released and Laravel introduced a new feature called login throttling, which made quite a few changes to the out-of-the-box user login and registration solution.
This meant that anyone following this tutorial was following something that was not going to work if they were using a fresh install of Laravel. So having learned from that mistake, I’ve decided to update this tutorial and preserve the original traits that come out of the box. That way if there is another change to a subsequent version, it should not break the code.
I think it’s best to “ride the lightning” of Taylor Otwell’s inventiveness and make the application as easy to maintain as possible. If you are unfamiliar with traits, you will learn a little about them in this tutorial. You can also check out this tutorial on traits.
Ok, here we go.
Part 1. The Routes
Let’s start by adding the following routes in routes file;
// Authentication routes...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
// Registration routes...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');
Route::controllers([
'password' => 'Auth\PasswordController',
]);
You can see we made a get and post route for both register and login and a get route for logout. We are also going to include a route for our PasswordController, which is also included out of the box. I have a separate tutorial for implementation of the forgot password functions, which I will also have to update for this latest version.
Part 2. AuthController
You do not need to create this file, it comes out-of-the-box, you can find it in app/Http/Controllers/Auth:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Create a new authentication controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}
While we’re here, we going to add one property that defines our redirectTo path:
private $redirectTo = '/';
So put that directly under the line:
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
Ok, you might be asking, where are all the methods for the login and registration actions? As in the previous versions, these are in the traits. We will return to those in a moment, but let’s first walk through what we have in the AuthController class.
I’ll skip the use statements and class declaration, those are pretty self-explanatory.
So moving along, we have the constructor:
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
What it’s doing here is limiting access to the methods to guests, except for the getLogout method. Obviously if you already authenticated, you do not need to login or register. However you would need to be able to logout, which is why we have this exception.
This is a beautiful example of the Laravel middleware at work. I will go deeper into that in a separate tutorial.
Next we have a validator method:
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
This is setting the rules for the form inputs. Obviously, if you want more fields on your form, you would add more rules here, and also to your DB and User model.
Next we have the create method:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
This method creates the new user upon registration.
Ok, so you can see there isn’t much on the surface of the AuthController. That’s because most of the methods are in the traits that we are using. We will cover those next.
Part 3. The Traits
Ok, so for anyone who doesn’t know, a trait is a class that can be used by multiple classes in a way that is like inheritance. You simply call the trait through the use statement and then all of the methods of the trait are available to the class that is using it. It’s a really cool and efficient way to handle code that will be reused by multiple classes.
I’m covering this to give you a quick idea of how it all works. We are not changing anything here however, so you can skip this part if you are in a hurry and want to go directly into the views.
Anyway, you can see AuthController uses 2 traits:
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
Let’s look at:
namespace Illuminate\Foundation\Auth;
trait AuthenticatesAndRegistersUsers
{
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
}
}
You can see this trait just pulls in two other traits, and also declares which method to use in case of conflict, since both traits, AuthenticatesUsers and RegistersUsers have a redirectPath method.
Ok, so we go another layer into AuthenticatesUsers:
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Cache;
trait AuthenticatesUsers
{
use RedirectsUsers;
/**
* Show the application login form.
*
* @return \Illuminate\Http\Response
*/
public function getLogin()
{
if (view()->exists('auth.authenticate')) {
return view('auth.authenticate');
}
return view('auth.login');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'password' => 'required',
]);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return redirect($this->loginPath())
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @param bool $throttles
* @return \Illuminate\Http\Response
*/
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::user());
}
return redirect()->intended($this->redirectPath());
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function getCredentials(Request $request)
{
return $request->only($this->loginUsername(), 'password');
}
/**
* Get the failed login message.
*
* @return string
*/
protected function getFailedLoginMessage()
{
return Lang::has('auth.failed')
? Lang::get('auth.failed')
: 'These credentials do not match our records.';
}
/**
* Log the user out of the application.
*
* @return \Illuminate\Http\Response
*/
public function getLogout()
{
Auth::logout();
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
/**
* Get the path to the login route.
*
* @return string
*/
public function loginPath()
{
return property_exists($this, 'loginPath') ? $this->loginPath : '/auth/login';
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function loginUsername()
{
return property_exists($this, 'username') ? $this->username : 'email';
}
/**
* Determine if the class is using the ThrottlesLogins trait.
*
* @return bool
*/
protected function isUsingThrottlesLoginsTrait()
{
return in_array(
ThrottlesLogins::class, class_uses_recursive(get_class($this))
);
}
}
And you can see this trait has all of our login methods. I’m not going to cover these in detail because we are not changing anything and we are simply using what is provided.
Let’s take a quick look at the RegistersUsers trait:
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
trait RegistersUsers
{
use RedirectsUsers;
/**
* Show the application registration form.
*
* @return \Illuminate\Http\Response
*/
public function getRegister()
{
return view('auth.register');
}
/**
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postRegister(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
Auth::login($this->create($request->all()));
return redirect($this->redirectPath());
}
}
And so this gives us the methods we need to register a user.
Obviously a benefit to separating out authenticating and registering into separate traits is a less bulky controller and a more focused codebase.
Our AuthController is also using the ThrottlesLogins trait:
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Cache;
trait ThrottlesLogins
{
/**
* Determine if the user has too many failed login attempts.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function hasTooManyLoginAttempts(Request $request)
{
$attempts = $this->getLoginAttempts($request);
$lockedOut = Cache::has($this->getLoginLockExpirationKey($request));
if ($attempts > $this->maxLoginAttempts() || $lockedOut) {
if (! $lockedOut) {
Cache::put(
$this->getLoginLockExpirationKey($request), time() + $this->lockoutTime(), 1
);
}
return true;
}
return false;
}
/**
* Get the login attempts for the user.
*
* @param \Illuminate\Http\Request $request
* @return int
*/
protected function getLoginAttempts(Request $request)
{
return Cache::get($this->getLoginAttemptsKey($request)) ?: 0;
}
/**
* Increment the login attempts for the user.
*
* @param \Illuminate\Http\Request $request
* @return int
*/
protected function incrementLoginAttempts(Request $request)
{
Cache::add($key = $this->getLoginAttemptsKey($request), 1, 1);
return (int) Cache::increment($key);
}
/**
* Redirect the user after determining they are locked out.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendLockoutResponse(Request $request)
{
$seconds = (int) Cache::get($this->getLoginLockExpirationKey($request)) - time();
return redirect($this->loginPath())
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getLockoutErrorMessage($seconds),
]);
}
/**
* Get the login lockout error message.
*
* @param int $seconds
* @return string
*/
protected function getLockoutErrorMessage($seconds)
{
return Lang::has('auth.throttle')
? Lang::get('auth.throttle', ['seconds' => $seconds])
: 'Too many login attempts. Please try again in '.$seconds.' seconds.';
}
/**
* Clear the login locks for the given user credentials.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function clearLoginAttempts(Request $request)
{
Cache::forget($this->getLoginAttemptsKey($request));
Cache::forget($this->getLoginLockExpirationKey($request));
}
/**
* Get the login attempts cache key.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function getLoginAttemptsKey(Request $request)
{
$username = $request->input($this->loginUsername());
return 'login:attempts:'.md5($username.$request->ip());
}
/**
* Get the login lock cache key.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function getLoginLockExpirationKey(Request $request)
{
$username = $request->input($this->loginUsername());
return 'login:expiration:'.md5($username.$request->ip());
}
/**
* Get the maximum number of login attempts for delaying further attempts.
*
* @return int
*/
protected function maxLoginAttempts()
{
return property_exists($this, 'maxLoginAttempts') ? $this->maxLoginAttempts : 5;
}
/**
* The number of seconds to delay further login attempts.
*
* @return int
*/
protected function lockoutTime()
{
return property_exists($this, 'lockoutTime') ? $this->lockoutTime : 60;
}
}
I’m not going to cover the entire trait, but I will say this is a cool feature that they have added to the login methods. It helps cut down on attacks from bots that will attempt to login over and over until it finds a successful user/pass combo.
It’s also easy to control the settings. You can see for example, that if you wanted to set the maxLoginAttempts to a number other than 5, you can include on your AuthController, a property:
private $maxLoginAttempts = 10;
That would get returned in the maxLoginAttempts method in the ThrottesLogins trait that the AuthController is using.
Part 4. Views
Ok, so now we need the views to support the registration and login forms.
A quick note about the app master page. A master page is a view file that would typically get included on every page. But instead of including it on other view pages, it works in reverse. The view pages are injected into the master page at specific locations.
I will write a separate tutorial for this, explaining it in more detail. For now, just know that we will be including the following into our views:
@extends('layouts.master')
@section('content')
// our view content goes here
@endsection
If you don’t have a master.blade.php file residing in a layouts folder inside of views, then don’t use this syntax at all and just use the what goes in between the @section tags.
Also note, that while we will be including a forgot password link on our login form, we have not yet built that functionality. I will build that will be a separate tutorial.
Ok, let’s create a couple of folders within our view folder. Our view folder is located at app/resources/views.
Make an auth folder and an email folder, each folder should reside directly under the views folder, so they have the following paths:
app/resources/views/auth
app/resources/views/email
We are creating the email folder because we will need it later in a subsequent tutorial, for now you can put an empty stub in there named password.blade.php.
Within the auth folder, make a register.blade.php file. For those unfamiliar, the convention we follow to use the blade template engine is viewname.blade.php. That tells the compiler it is a blade file and compiles it for you.
I’m going to provide a gist here, which has the code and will open in a new tab. You can copy the code from here:
A lot of this is just straight Twitter Boostrap, so if you are unfamiliar with that, I suggest you take some time to visit getbootstrap. Our tutorial is not going to teach you html or css. We will be focusing on the blade specific elements and the content specific to our application, in this case the registration form.
Ok, so the first item of interest to us in the Gist is the if statement that holds the errors. Here we are using Blade’s @if syntax to make the interspersing of html and php a pleasure to work with.
As you might already be aware, the $errors object is always available to the views. That means we can use a simple foreach loop to parse and print. So if the count of errors is greater than 0, then we serve a notice:
Whoops! There were some problems with your input.
We follow that with the @foreach, using $error as the local variable, then we use the {{ }} syntax, which is short for , to print each error as a list item.
Normally what you will do is extract this block out to view partial and just include it with the line:
@inlcude(‘errors.errors’)
This would assume you have an errors folder inside the views folder with view file named errors.blade.php.
For this tutorial, we are leaving it in the main view, but you’ll certainly want to extract as I’ve described above because it doesn’t make sense to repeat this code.
Ok, let’s move on to the form itself. We open it with:
<form class="form-horizontal" role="form" method="POST" action="/auth/register">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
Note that there are two ways to begin the form. The manual way is how we are doing it here. But Laravel also has a helper class that allows you to do it as follows:
{!! Form::open(array('url' => '/auth/register, 'class' => 'form-horizontal')) !!}
You can see this is a lot simpler and it includes the CSRF token for you automatically.
If you want to do it that way, you need to pull in the illuminate Html helper class, which you can find at:
https://github.com/illuminate/html
Just follow the instructions there.
Anyway, for now we are going to stick with:
<form class="form-horizontal" role="form" method="POST" action="/auth/register">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
Next we have our form-group for the name input field. Refer to the Gist for the code.
You can see we also have a value of {{ old(‘name’) }} so that the form remembers the input. Otherwise, this is just standard bootstrap form syntax.
Next we have the two password fields, so the user is typing in what they intend and not making a typo. But how does it know to compare the two password fields and validate them?
IF you remember, we had in our validator method in our AuthController:
'password' => 'required|confirmed|min:6',
You can see the middle rule is confirmed, so it’s looking for password_confirmation from the form post and performs its validation. This is unbelievably easy to work with, since you don’t have to set up a class property or do anything else for it.
If you wanted to confirm any other input, you would simply use the _confirmation syntax on the 2nd field and then make sure you had confirmed as one of the validation rules.
Finally, we have the submit button and closing form tag and that should get you a working registration form.
Note: If for some reason you passing validation but not saving to the DB, check the $fillable property on your User class, which is located in the app directory. You have to explicitly name the properties which are mass assignable.
protected $fillable => ['name', 'email', 'password'];
Ok, let’s move on to the login view. Let’s create a login.blade.php file within the app/resources/views/auth folder with the following contents:
Ok, so we have the errors section again, which just points to how much better it would be in a partial, as I described in the registration view section. Then we come to the login form itself, which starts as we would expect:
<form class="form-horizontal" role="form" method="POST" action="/auth/login">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
Next we get the email and password fields, nothing new here, so I won’t list it again.
Then we get a checkbox for the remember me, which if checked will set a cookie. The value of remember gets passed in the Auth::attempt method in the AuthenticatesUsers trait:
if (Auth::attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
Then we get the submit button and forgot password link and that should be it, you should now have a working user registration and login. You should be able to test the following routes:
yourapp.com/auth/login
yourapp.com/auth/register
yourapp.com/auth/logout
I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials. Please comment, share, and like if you can, thanks.
I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.
Hi, this is great tutorial, would be amazing to add code example on github to have everything on one place, and maybe other people could extend/improve your code
Thank you.
LikeLiked by 1 person
Note to everyone: This tutorial is for Laravel 5.1.11, which as of 10/16/2015 is the latest stable release. If you are using the master, there may be differences that I have not accounted for. When the next release is made, I will update the tutorial if necessary.
Thanks for the positive feedback, I appreciate your encouragement. I will keep your suggestion in mind for the future. Thanks again.
LikeLike
Thanks for the Tutorial.After press submit i receive this on page?
Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
If you think this is a server error, please contact the webmaster.
Error 404
localhost
Apache/2.4.12 (Win32) OpenSSL/1.0.1m PHP/5.6.11
LikeLike
can you give me a little more information? Are you trying to submit a registration? Did you check for typos in your route?
LikeLike
The error message is the same like the 404 of basharmomin77, but in my case it’s in german. So it doesn’t look like a laravel message. I think there is no connection between register.blade.php and routes.php.
LikeLike
If you follow the tutorial and have your routes and views set correctly, it will work with a fresh install of Laravel. If it is not working you may have an environment issue. I have never seen an error message from Laravel that was written in German….
LikeLike
Just an update, I did add the views to Github in two separate gists, so it is really easy to grab the view code. The controller code is already provided out of the box, so no need to provide that. The routes are given in the tutorial and are easy to copy in one go. Thanks everyone for all the great feedback.
LikeLike
I also got the same erros message like basharmomin77 at the registration of a user:
object not found!
I copied the blade registration from the laravel site.
What can be the problem?
LikeLike
Can you provide more of the error message?
LikeLike
scratch that I can get login to display but not reg – the error is View [reg.register] not found.
LikeLiked by 1 person
Hi Casey. Look for typos in your view, especially in @extends(‘layouts.master’) and @section(‘content’). Make sure you folder structure is correct. You should have a layouts folder in views, with a master.blade.php file in it. Also I had a typo in the tutorial that made the name of the reg folder unclear. I’ve corrected that, so you just need make sure that you have a folder named reg inside of views that will hold the register.blade.php view.
Remember to name your view files viewname.blade.php. Here is a link to the docs on views. Also a good laracasts video for basic routing and views. It’s free.
To get to your view, the url: localhost:8000/projectfolder/your-route-to-controller-action should work. The controller action should return the view. In the case of reg in my tutorial, If you are able to load the welcome page, localhost:8000/projectfolder/reg should work.
In the RegistrationController, you want the register method to return view(‘reg.register’).
Syntax errors in views will cause white pages. Route/controller/view folder errors will cause view not found errors.
I hope this helps.
LikeLike
i solved the problem – i had successfully logged in so to view the registration i had to log out, thanks for you’re reply!
LikeLike
hi
i got an error
[2015-06-27 07:49:48] local.ERROR: exception ‘Symfony\Component\Debug\Exception\FatalErrorException’ with message ‘Trait ‘App\AuthTraits\RedirectsUsers’ not found’ in B:\projects\laravel5\app\Http\Controllers\Login\LoginController.php:15
Stack trace:
#0 {main}
LikeLike
add use App\AuthTraits\RedirectsUsers; to the top of the file and you should be good. Or check the namespace in RedirectsUsers.php, it should be App\AuthTraits. Also note that you must use uppercase A for App. One of these solutions should solve your problem. If none of those work, try running composer dump-autoload from the command line.
LikeLike
Hi I have checked and i have namespaces and imports right although I am still getting this error…
Whoops, looks like something went wrong.
1/1
FatalErrorException in RegistrationController.php line 17:
Trait ‘App\AuthTraits\RedirectsUsers’ not found
in RegistrationController.php line 17
Many thanks for your help
LikeLike
Is your AuthTraits folder directly under the app folder? And is the RedirectsUsers.php file inside of the AuthTraits folder? Do you have the following inside your RedirectsUsers file:
namespace App\AuthTraits;
trait RedirectsUsers
{
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
if (property_exists($this, ‘redirectPath’)) {
return $this->redirectPath;
}
return property_exists($this, ‘redirectTo’) ? $this->redirectTo : ‘/home’;
}
}
LikeLike
try cek your filename in app/authtraits. redirect or redirects
LikeLike
thanks.. it is really good tutorial..
but i still confuse, how i set some controller that user could access without login..
LikeLike
Hi Daniel. If I understand your question, you are asking how to leave a route/controller open so that it does not require login. A route/controller will not require login by default, so if you want a route that is wide open, it will operate that way normally, you don’t have to do anything special to it.
LikeLike
in my case i have a website and i build using laravel 5.1
how i set only home.index that doesnt need login, but if user access admin page it need login
LikeLike
I will be covering that in a separate tutorial. It would take to too long to explain in a comment. The tutorial will be a bout Middleware implementations, so you can look that up if you need to work on it immediately.
LikeLike
Hi,
I noticed that oddly enough (at least for me), the logout function in LoginController.php gets triggered regardless of the middleware. I added a small check to compensate:
public function logout() {
if(Auth::guest()) return redirect(‘/’);
Auth::logout();
return redirect(property_exists($this, ‘redirectAfterLogout’) ? $this->redirectAfterLogout : ‘/’);
}
The real question is, why does logout get triggered regardless of the guest middleware (for me)?
LikeLike
hy bill, nice tutorial, but after logout i still have an access into my other controller that require login first, where is my mistake?
please make a tutorial that describes the page that requires a login and pages that do not need to login, example is homepage and admin page
LikeLike
Hi Leo. You need to require login on those other routes or controllers. I will do a separate tutorial for that in the future. Meanwhile, you should check out the Laracasts video on middleware: https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/9
LikeLike
hi!
in credentials is it possible to use email or username?
LikeLike
Not sure I understand the question. The tutorial is set up to use email and password for credentials. If you want to change to username instead of email, that should be a relatively easy change, just make the changes to the form and the LoginController. If you want a form where the user can enter either an email or a password, this is of course possible, but beyond the scope of this tutorial.
LikeLike
Hi, really nice tutorial, you saved my day!
2 things…
1)
I’m having trouble understanding and getting the “error” part to work.
Either he default validation errors in resources/lang/ seem to override this getFailedLoginMessage method or I’m doing something wrong. I’ve dd(‘test’) in the getFailedLoginMessage method and It’s not even calling that method.
public function postLogin(Request $request)
{
$this->validate($request, [
’email’ => ‘required|email’, ‘password’ => ‘required’,
]);
$credentials = $this->getCredentials($request);
if (Auth::attempt($credentials, $request->has(‘remember’))) {
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only(’email’, ‘remember’))
->withErrors($this->getFailedLoginMessage());
}
And what does ’email’ mean in the section below? I understand $this->getFailedLoginMessage, that doesnt work… hehe.. but what is the ’email’ part for?
->withErrors([
’email’ => $this->getFailedLoginMessage(),
]);
2)
I was not able to get the logout() method to work, it just redirected me back to the same page without being called at all, verified through dd(). I had to rename it getLogout() to make it work.
Do you know why?
Build laravel/laravel 5.1.7 and .8
Many thanks Bill!
LikeLike
It all works for me. Thank you for listing the version number. I did my build with Laravel 5.1, so it’s possible that something has changed. When I get time, I will rebuild in the latest version and see if there are any problems. I believe ’email’ refers to the input from the request, but keep in mind I did not write that part, it was part of the AuthenticatesAndRegistersUsers traits from the original build. I just moved the code up to a login controller to make it easier to work with. If you find your solution, please come back and add it via comment, so others will know if this is a version problem or just a bug on your part. Thanks!
LikeLike
Thank’s bill, but i have a little problem here,
When i try to logout I get this error :
ErrorException in LoginController.php line 97: Undefined property: App\Http\Controllers\Login\LoginController::$redirectAfterLogout
LikeLike
if you don’t have redirectAfterLogout defined as a property it should redirect to “/” if you have the logout method as follows:
public function logout()
{
Auth::logout();
return redirect(property_exists($this, ‘redirectAfterLogout’) ? $this->redirectAfterLogout : ‘/’);
}
LikeLike
I used that method, but i still get this error..
LikeLike
Could you give me an example how to define ‘redirectAfterLogout’ as property?
LikeLike
User Login and Registration tutorial updated today and is now current for Laravel 5.1.4.
LikeLike
Am I missing something, but i can’t see the code for the master.blade.php file. Can you tell me what this file contains.
LikeLike
The code for the master page is not provided. If you are not using a master page, remove that line. If you need to learn how to setup a master page, see my other tutorial https://laraveltips.wordpress.com/category/master-page-in-laravel-5-1/
LikeLike
Thank you sooooo very much – I was very confused using 5.1 and the lessons were of older versions.
LikeLike
Hey! Thanks for the tutorial, but I keep getting this mistake when I use the postman: NotFoundHttpException in RouteCollection.php line 143
I commented the line of csrftoken verification on kernel to be able to use the google postman.
LikeLike
I’m not sure what you are referring to. Google postman is not part of the tutorial.
LikeLike
Hi Bill.
This tutorial is good for me, but am getting this error.
Whoops, looks like something went wrong.
QueryException in Connection.php line 636: SQLSTATE[42S22]: Column not found: 1054 Unknown column ’email’ in ‘where clause’ (SQL: select count(*) as aggregate from `users` where `email` = avc@gmail.com)
LikeLike
Check to see if you have an email column in your users table. You should have it after running the initial migration. Also, check my DB setup tutorial: https://laraveltips.wordpress.com/category/database-setup-in-laravel-5-1/
LikeLike
Hi Bill
Nice tutorial, but when we register could it be go to login view?
LikeLike
In the out-of-the-box solution, once you register, you are automatically logged in, so if you want to change that, you could overwrite some methods in the RegistersUsers trait on the Auth controller.
LikeLike
thx. before I thought it was redirect when we register
LikeLike
Hi Bill,
I only get blank pages for
~localhost:8000/auth/login
~localhost:8000/auth/register
~localhost:8000/auth/logout
Kindly advice.
LikeLike
There a number of reasons why this can happen. If you have a syntax error in your login.blade.php file for example or the environment is not setup properly, which would probably return an error and not a blank page. I always use local host entries with my projects, so my urls look like:
myproject.com/auth/login
and it works perfectly fine.
LikeLike
I’m having trouble at register, i want to access the registration form when and only the admin is logged in.. the access for the registration is guest by default, but when i add middleware=>auth into the registration route, it redirects me at my home… please, i need your help, thanks in advance…
LikeLike
Sorry, I’m not sure I understand the problem. If the admin is logged in, they cannot register. Do you mean you want to add new users via admin only, without a registration form?
LikeLike
Hey BIll
I checked my authcontroller and it doesn’t have a getlogin function which i thnk that causes the route to return a blank page.
howsthat should go?
LikeLike
getLogin is in the trait, not the controller. It’s not the problem…
LikeLike
Disregard my previous comment.
now im having View [auth.login] not found error
how am i able to fix this?
LikeLike
This error indicates that you do not have folder named auth in your view folder or that you do not have a login.blade.php file within the auth folder.
LikeLike
Nice Tutorial!
im having trouble when i try to click the login button, im redirected to a url which is not found how am i able to solve this problem..
any advice will be appreciated
TIA.
LikeLike
You need to set the redirectTo property on your AuthController:
private $redirectTo = ‘/’;
That is of course assuming you have a route setup for ‘/’. You can set the redirectTo property to any valid uri.
LikeLike
Hi,
im new to laravel. i successfuly installed Laravel and getting the welcom page from laravel.
but when i tried to follow your added codes and put localhost/laraproj/public/auth/login it says the not found
thnx in advance
LikeLike
Try just using /auth/login
LikeLike
Im having troubles viewing pages after something is inside the database. When I remove the item in the database it works fine but after registrering or manually inserting into database it gives me : NotFoundHttpException in RouteCollection.php line 143:
LikeLike
Is it possible that you have not set you redirectTo property to a valid uri?
LikeLike
Hi!
why im getting this error whenever i try to login
TokenMismatchException in C:\wamp\www\LaravelFive\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php line 53:
LikeLike
make sure you have:
in the login form in your login view.
LikeLike
(y)
LikeLike
Hi,
Thanks for the nice tutorial,
But I have a different senario here, I have two tables named as users and admin that store the user credentials and the admin credentials respectively, And I want to create the different login view and postLogin functionality that acts independent to one another, such as login from admin hits to the admin dashboard and login from user section hits to the user dashboard.
I followed the suggestion from http://stackoverflow.com/questions/31270025/laravel-5-how-to-work-with-authentication-on-two-different-login-forms-with-diff
But when the users login in the user can also can view the admin dashboard and when the users log out the admin also gets log out.
Could please help me out with this ?
Great Thanks…
LikeLike
I don’t think it’s wise to have separate logins for the reasons that you are experiencing. My tutorial did not cover roles, but that’s something I’ve been working with. The simple version would be to create a is_admin field on the user record, detect that on login and redirect to the admin page. If you have multiple admin roles, then you need a separate data structure. Either way, that is beyond the scope of this tutorial.
LikeLike
Hi. I’m new to laravel 5.1. I cant figure out part 3-Traits that you’d mention. 🙂
LikeLike
The traits are included out of the box, so I’m just reviewing them, you don’t actually have to code anything. Here is a nice tutorial on traits: http://culttt.com/2014/06/25/php-traits/
LikeLike
This is confusing me too! I don’t have an appTraits folder, or an illuminate/foundation folder in vendors, and cannot find any reference to AuthenticatesAndRegistersUsers other that in the AuthController. what does all this refer to?
LikeLike
You have to drill down to find the parts you will recognize, such as getLogin. That is found in the AuthenticatesUsers trait, which is found in your vendor/laravel/framework/src/Illuminate/Foundation/Auth folder. I recommend re-reading the tutorial and then following that up with reading about traits in PHP. This was tough for me to get initially too, but once you understand how traits work and how they help keep your code clean. It’s gotten a bit more complicated since they added the ThorttlesLogins trait, but that is a really cool feature. Just keep working with it, eventually you will get it.
LikeLike
Hi
What should I do if I want to change my login view from auth folder to any other folder ???
LikeLike
You would need to change the getLogin method on the AuthenticatesUsers trait to point to the view you want. Here is a tip. I prefer not to make changes to the out of the box traits that ship with Laravel. Instead, I overwrite the method in the AuthController. That way, when I run composer update, I’m not overwriting custom code.
LikeLike
Bill your tutorial = amazing
could you edit a miss html in here :
E-Mail Address
E-Mail Address
for newbie like me, this will be very helpful
LikeLike
please be more clear in what you are asking for, thanks…
LikeLike
Hey Bill,
Thanks for this straight forward tutorial. Very simple and easy to follow.
One thing I did run into though.
I think there’s a typo in your tutorial that is causing an error when you visit yourapp.com/auth/login
“Let’s create a login.blade.php file within the app/resources/views/login” should be “app/resources/views/auth”?
I was following the tutorial and created a “login” folder to put login.blade.php in it. When visiting yourapp.com/auth/login I get the following error
InvalidArgumentException in FileViewFinder.php line 137:
Once I moved login.blade.php into the app/resources/views/auth folder everything was fine.
LikeLike
Thanks for pointing out the typo. I corrected it and moved the view files into Gists for easy copying and pasting and to avoid format problems with wordpress.
LikeLike
Hi Bill, great tutorial!
I am new to laravel.
I follow ur tutorial and it work. but i facing a weird situation. When i register new user it keep saying i havent fill the required form( like name). how to solve this problem?
LikeLike
This can happen when the in put name does not match the name you have set in validation. In the case of the tutorial, it is looking for name, email, and password. Make sure that matches what you are trying to validate.
LikeLike
Great job, this tutorial let me know more about Laravel 5.1.
I can do the Register, and new user store in the to database.
but for the login, I got some error after user login when I try to get some user information
$user = Auth::user()->name;
return $user;
It said: ErrorException in ArticlesController.php line 19: Trying to get property of non-object
and I can logout.
thx Bill
LikeLiked by 1 person
The problem seems to be in your ArticlesController. That is not native to the tutorial. Make sure you are using the Auth facade in that controller: use Illuminate\Support\Facades\Auth;
LikeLike
thx Bill, I am not sure, because I am using Illuminate\Support\Facades\Auth; the tutorial is base on 5.0, but I am starting in 5.1.17…….
I am still finding the answer, and will post here if I fixed it.
LikeLike
I did all these. But when I tried to register it brings me a page with “Forbidden” on it. Any reason why?
LikeLike
You’re not really giving me enough information to help you. Is it a permissions issue with your server? What is the url of the page returning forbidden? Do you have a mistake in the middleware?
LikeLike
The url of my register form page is /auth/register as the same as this page that ha only “Forbidden” on it. I don’t think it’s a server permission issue. How do I check for a middleware mistake?
LikeLike
did you follow this tutorial from a fresh install of laravel 5.1? did you run the migration, add the route files? Did you set the .env settings to your DB? The middleware is set in the constructor of the auth controller and should be:
$this->middleware(‘guest’, [‘except’ => ‘getLogout’]);
LikeLike
Hello There,
If you are still looking for the answer I guess you didn’t change your Authorization sttaus from False => True
Best of luck
LikeLike
I already use Laravel 5.1. I ran the migration, added the route file. There is DB connection too… also this middleware is present. It is just strange to me.
LikeLike
I’m doing a fresh install in the next couple of days and will post here if I find anything.
LikeLike
Okay. Will be expecting.
LikeLike
I was able to successfully register a user with a fresh install, following the tutorial. A common error is to forget to set the private $redirectTo = ‘/’; property on the AuthController. I don’t know if that is your problem or not. If that doesn’t solve your problem, I would recommend using dd(), which is die dump to increment your way along the process and figure out where it is breaking. The trait is kind of complicated and it will be a pain, but on the other hand, you will learn a lot about the trait. Good luck.
LikeLike
hi great tutorial but i am unfortunately stuck. I just started learning laravel 3 days ago and i seem to be making no progress at all. I simply can’t route to any page! except public, why? i copied your auth folder and all in the reources/views but it gives me a 404 not found error. I don’t understand this whole routing thing at all. The only page i can go to is the public/. Please your explanation would be highly appreciated
LikeLike
sounds like a simple error, please check your routes, your controllers, and your views for the proper paths and names.
LikeLike
I have fixed it. I simply install a laravel again. Now when i try to register it gives me this: NotFoundHttpException in RouteCollection.php line 161: Please help
LikeLike
You should run php artisan route:list and see if your route is there. Also view page source to see:
action: /auth/register and the type POST
Also, there is a thread for similar problems on Laracasts:
https://laracasts.com/discuss/channels/laravel/notfoundhttpexception-in-routecollectionphp-line-161-1
If you were pulling the registration form code from the gist I provided, I have just updated it to use raw html instead of the form helper class.
You can use the form helper by installing the package found at http://laravelcollective.com/docs/5.0/html. If you tried using it and you didn’t have the form helper installed, it should have thrown an error complaining about not finding the helper, but just incase, you should try the updated version, which is just plain html. Don’t forget the hidden field for the token.
And lastly, make sure your route syntax is exact, any typo will cause an error. Hope that helps.
LikeLike
Thank you, I have succeeded in registering and its taking me to public/home. The problem is i cant register again because it keeps redirecting me to home(which doesn’t even exist).Does it allow registering only once on a system? is that the problem? I thought i could keep registering other users. Thanks
LikeLike
It’s because you are logged in. You can’t be logged in and register. Go to /auth/logout and that will log you out, then you can register.
LikeLike
Hi, everything is working okay now. My stumblings in this tutorial has given a better understanding of the framwork. Thank you, keep doing your great work
LikeLike
Thanks, sticking with it always pays off.
LikeLike
This is a great guide.
I have implemented the master page, which works great. The problem is when i try to access the register page (or login for that matter, and any other page.) i get a 404 page not found which i don’t get. do you know what the problem might be?
i am running laravel 5.1.19 where the file structure seems to be a bit different.
Regards Troels
LikeLike
I have implemented the master.blad.php which works fine. my problem is that the links to the reistration and login files gives a 404 page not found. do you hav any idea what might cause this?
im using laravel 5.1.19 which seems to have a slightly different structure than the one described in the tutorial.
otherwise a great guide.
LikeLike
Can you tell me what you think the difference in the structure is? Meanwhile I will check it out myself…
LikeLike
The current release is 5.1.11, which the tutorial supports. It looks like you may be working with the master branch, let me know if you can see if there is a difference in the traits that would point the route to something other than auth.login and auth.register.
LikeLike
I found te problem. It was a typo in the vhost file. Now it all works. Thanks for your time, and help.
LikeLike
Well, I’m glad to know that 5.1.19 isn’t going to break everything 🙂
LikeLike
Very very useful, very tks for your tutorial, helped me a lot.
LikeLike
Thank you!
LikeLike
Hi Bill, this tutorial is awesome. 🙂
1. Now, when I try to register by filling the form, it does not show error inspite of code written for showing error on login.blade.php and register.blade.php.
@if (count($errors) > 0)
Whoops! There were some problems with your input.
@foreach ($errors->all() as $error)
{{ $error }}
@endforeach
@endif
2. When I submit the form, both login and register, the page gets directed to :/home. But I have already mentioned (see below) in my AuthController.
protected $redirectPath = ‘pages/dashboard’;
protected $loginPath = ‘auth/login’;
3. My Routes.php looks like:
// Authentication routes…
Route::get(‘auth/login’, ‘Auth\AuthController@getLogin’);
Route::post(‘auth/login’, ‘Auth\AuthController@postLogin’);
Route::get(‘auth/logout’, ‘Auth\AuthController@getLogout’);
// Registration routes…
Route::get(‘auth/register’, ‘Auth\AuthController@getRegister’);
Route::post(‘auth/register’, ‘Auth\AuthController@postRegister’);
Route::controllers([
‘password’ => ‘Auth\PasswordController’,
]);
// Pages routes
Route::get(‘/’, function () {
return view(‘welcome’);
});
Route::get(‘auth/login’, function() {
return view(‘auth/login’);
});
Route::get(‘auth/register’, function() {
return view(‘auth/register’);
});
Route::get(‘pages/dashboard’, function() {
return view(‘pages/dashboard’);
});
So, my issue is my Validator is not working (as no error when when password less than 6 character)
Also, why it is redirecting page to /home when I have mentioned to do redirect to : pages/dashboard.
THANK YOU!!!
LikeLike
You want to use the redirectTo property, not redirectPath for setting your redirect. I have not used loginPath property as you have, but I noticed in the trait, it is ‘/auth/login’, so you might be missing a backslash. If the validation rule is not being enforced, it would explain why you are not seeing the error. I hope that helps.
LikeLike
Hi.. Thanks for the prompt reply. I just saw one of your reply above, which mentioned to go to auth/logout as without logout we cannot register again. As this was the problem I was facing, which is solved now 🙂
Also, for the redirectpath and Loginpath property, these have been taken from laravel 5.1 documentation.
But thanks a lot for getting my stuff done which has only become possible because of yours detailed and clear explanation.
LikeLike
Thank you! Positive comments, reviews and referrals are alway appreciated…
LikeLike
Hi Bill. Your tutorials are nice and understandable.
I have followed your tutorials closely but i have gotten a problem when i submit registration details.
when i visit http://localhost/myproject/auth/register it works well but after submitting registration details i get http://localhost/auth/register and ‘Object not found’.
What could be the problem.
I will appreciate your assistance
LikeLike
Is it actually saving to the DB? Is it a problem with the return route?
LikeLike
I followed this guide, but when I try to login I get this:
Login
Whoops! There were some problems with your input.
The email has already been taken.
The password confirmation does not match.
E-Mail Address
LikeLike
There is no password confirmation on login, check the action on the login form view to make sure it is not posting to registration
LikeLike
You are right… I realized later that this is probably what I did since I copy and pasted something into action=”” . Thanks! 🙂
LikeLike
It’s fair to say when something is well done and this tutorial is the best ever. Congratulations. It was very helpful. Keep working that way.
LikeLike
Thank you!
LikeLike
Hi Bill,
Thank you for such a nice tutorial. Everything worked very well. But when I wanted to add a new field in my registration form, it became problematic. When I try to submit my form It says,
Whoops, looks like something went wrong.
1/1 BadMethodCallException in Validator.php line 2638:
Method [validateUsername] does not exist.
Can you please help me to solve the problem???
LikeLike
Sorry, that’s beyond the scope of the tutorial. It gets complex because of the traits. You could overwrite some of the trait methods in the auth controller to account for the new attribute. You have to work your way through the trait to see how everything is being used…
LikeLike
Thanks for the great tutorial! I followed it and now have a working login system. My question is how to get the current authenticated user object from within a Controller. I found various sources online, like calling a static Auth::user(); but that doesn’t seem to work, I also don’t know what namespace the Auth class is supposed to live in. Could you help me here? Thanks!
LikeLike
Are you getting a class not found error? If so, make sure to include the use statement:
use Illuminate\Support\Facades\Auth;
LikeLike
Hi
can you upload full code for user login registration and password remind for latest laravel 5.1?
Best regards
LikeLike
The full code is in a fresh install, you only need routes and views, which I have provided in the tutorial.
LikeLike
Halo, thanks for the tutorial. Iam using Laravel 5.1.24 and i follow your instruction and i got the register work by accessing localhost/laraexam/public/auth/register but when i tried to register and push the register button, it just jumped into localhost/auth/register & object not found. and i cant found the id that i just input in the database. can you help me?
Thank you so much.
LikeLike
It looks to me like your environment is not setup properly. Have you tried downloading something like MAMP and setting up a vhost?
LikeLike