- Retrieving The Authenticated User
- Determining If The Current User Is Authenticated
- Redirecting Unauthenticated Users
- Specifying A Guard
- Manually Authenticating Users
- Specifying Additional Conditions
- Accessing Specific Guard Instances
- Remembering Users
- Other Authentication Methods
- Authenticate A User Instance
- Authenticate A User By ID
- Authenticate A User Once
- HTTP Basic Authentication
- Stateless HTTP Basic Authentication
- Logging Out
- Invalidating Sessions On Other Devices
- Routing
- The Password Confirmation Form
- Protecting Routes
- Adding Custom Guards
- Events
Retrieving The Authenticated User
After installing an authentication starter kit and allowing users to register and authenticate with your application, you will often need to interact with the currently authenticated user. While handling an incoming request, you may access the authenticated user via the Auth facade's user method:
use Illuminate\Support\Facades\Auth;
// Retrieve the currently authenticated user...
$user = Auth::user();
** Retrieve the currently authenticated user's ID...**
$id = Auth::id();
Alternatively, once a user is authenticated, you may access the authenticated user via an Illuminate\Http\Request instance. Remember, type-hinted classes will automatically be injected into your controller methods. By type-hinting the Illuminate\Http\Request object, you may gain convenient access to the authenticated user from any controller method in your application via the request's user method:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FlightController extends Controller
{
/**
* Update the flight information for an existing flight.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
// $request->user()
}
}
Determining If The Current User Is Authenticated
To determine if the user making the incoming HTTP request is authenticated, you may use the check method on the Auth facade. This method will return true if the user is authenticated:
use Illuminate\Support\Facades\Auth;
if (Auth::check()) {
// The user is logged in...
}
Even though it is possible to determine if a user is authenticated using the check method, you will typically use a middleware to verify that the user is authenticated before allowing the user access to certain routes / controllers. To learn more about this, check out the documentation on protecting routes.
Protecting Routes
Route middleware can be used to only allow authenticated users to access a given route. Laravel ships with an auth middleware, which references **the Illuminate\Auth\Middleware\Authenticate **class. Since this middleware is already registered in your application's HTTP kernel, all you need to do is attach the middleware to a route definition:
Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth');
Redirecting Unauthenticated Users
When the auth middleware detects an unauthenticated user, it will redirect the user to the login named route. You may modify this behavior by updating the redirectTo function in your application's app/Http/Middleware/Authenticate.php file:
/**
- Get the path the user should be redirected to. *
- @param \Illuminate\Http\Request $request
- @return string */
protected function redirectTo($request)
{
return route('login');
}
Specifying A Guard
When attaching the auth middleware to a route, you may also specify which "guard" should be used to authenticate the user. The guard specified should correspond to one of the keys in the guards array of your auth.php configuration file:
Route::get('/flights', function () {
// Only authenticated users may access this route...
})->middleware('auth:admin');
Login Throttling
If you are using the Laravel Breeze or Laravel Jetstream starter kits, rate limiting will automatically be applied to login attempts. By default, t*he user will not be able to login for one minute if they fail to provide the correct credentials after several attempts. The **throttling is* unique to the user's username / email address and their IP address.
If you would like to rate limit other routes in your application, check out the rate limiting documentation.
Manually Authenticating Users
You are not required to use the authentication scaffolding included with Laravel's application starter kits. If you choose not to use this scaffolding, you will need to manage user authentication using the Laravel authentication classes directly. Don't worry, it's a cinch!
We will access Laravel's authentication services via the Auth facade, so we'll need to make sure to import the Auth facade at the top of the class. Next, let's check out the attempt method. The attempt method is normally used to handle authentication attempts from your application's "login" form. If authentication is successful, you should regenerate the user's session to prevent session fixation:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Handle an authentication attempt.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function authenticate(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
return back()->withErrors([
'email' => 'The provided credentials do not match our records.',
])->onlyInput('email');
}
}
The attempt method accepts an array of key / value pairs as its first argument. The values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the email column. If the user is found, the hashed password stored in the database will be compared with the password value passed to the method via the array. You should not hash the incoming request's password value, since the framework will automatically hash the value before comparing it to the hashed password in the database. An authenticated session will be started for the user if the two hashed passwords match.
Remember, Laravel's authentication services will retrieve users from your database based on your authentication guard's "provider" configuration. In the default config/auth.php configuration file, the Eloquent user provider is specified and it is instructed to use the App\Models\User model when retrieving users. You may change these values within your configuration file based on the needs of your application.
The attempt method will return true if authentication was successful. Otherwise, false will be returned.
The intended method provided by Laravel's redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware. A fallback URI may be given to this method in case the intended destination is not available.
Specifying Additional Conditions
If you wish, you may also add extra query conditions to the authentication query in addition to the user's email and password. To accomplish this, we may simply add the query conditions to the array passed to the attempt method. For example, we may verify that the user is marked as "active":
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication was successful...
}
For complex query conditions, you may provide a closure in your array of credentials. This closure will be invoked with the query instance, allowing you to customize the query based on your application's needs:
if (Auth::attempt([
'email' => $email,
'password' => $password,
fn ($query) => $query->has('activeSubscription'),
]) {
// Authentication was successful...
}
In these examples, email is not a required option, it is merely used as an example. You should use whatever column name corresponds to a "username" in your database table.
The attemptWhen method, which receives a closure as its second argument, may be used to perform more extensive inspection of the potential user before actually authenticating the user. The closure receives the potential user and should return true or false to indicate if the user may be authenticated:
if (Auth::attemptWhen([
'email' => $email,
'password' => $password,
], function ($user) {
return $user->isNotBanned();
})) {
// Authentication was successful...
}
Accessing Specific Guard Instances
Via the Auth facade's guard method, you may specify which guard instance you would like to utilize when authenticating the user. This allows you to manage authentication for separate parts of your application using entirely separate authenticatable models or user tables.
The guard name passed to the guard method should correspond to one of the guards configured in your auth.php configuration file:
if (Auth::guard('admin')->attempt($credentials)) {
// ...
}
Remembering Users
Many web applications provide a "remember me" checkbox on their login form. If you would like to provide "remember me" functionality in your application, you may pass a boolean value as the second argument to the attempt method.
When this value is true, Laravel will keep the user authenticated indefinitely or until they manually logout. Your users table must include the string remember_token column, which will be used to store the "remember me" token. The users table migration included with new Laravel applications already includes this column:
use Illuminate\Support\Facades\Auth;
if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}
If your application offers "remember me" functionality, you may use the viaRemember method to determine if the currently authenticated user was authenticated using the "remember me" cookie:
use Illuminate\Support\Facades\Auth;
if (Auth::viaRemember()) {
// ...
}
Other Authentication Methods
Authenticate A User Instance
If you need to set an existing user instance as the currently authenticated user, you may pass the user instance to the Auth facade's login method. The given user instance must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract. The App\Models\User model included with Laravel already implements this interface. This method of authentication is useful when you already have a valid user instance, such as directly after a user registers with your application:
use Illuminate\Support\Facades\Auth;
Auth::login($user);
You may pass a boolean value as the second argument to the login method. This value indicates if "remember me" functionality is desired for the authenticated session. Remember, this means that the session will be authenticated indefinitely or until the user manually logs out of the application:
Auth::login($user, $remember = true);
If needed, you may specify an authentication guard before calling the login method:
Auth::guard('admin')->login($user);
Authenticate A User By ID
To authenticate a user using their database record's primary key, you may use the loginUsingId method. This method accepts the primary key of the user you wish to authenticate:
Auth::loginUsingId(1);
You may pass a boolean value as the second argument to the loginUsingId method. This value indicates if "remember me" functionality is desired for the authenticated session. Remember, this means that the session will be authenticated indefinitely or until the user manually logs out of the application:
Auth::loginUsingId(1, $remember = true);
Authenticate A User Once
You may use the once method to authenticate a user with the application for a single request. No sessions or cookies will be utilized when calling this method:
if (Auth::once($credentials)) {
//
}
HTTP Basic Authentication
HTTP Basic Authentication provides a quick way to authenticate users of your application without setting up a dedicated "login" page. To get started, attach the** auth.basic middleware to a route**. The auth.basic middleware is included with the Laravel framework, so you do not need to define it:
Route::get('/profile', function () {
// Only authenticated users may access this route...
})->middleware('auth.basic');
Once the middleware has been attached to the route, you will automatically be prompted for credentials when accessing the route in your browser. By default, the auth.basic middleware will assume the email column on your users database table is the user's "username".
A Note On FastCGI
If you are using PHP FastCGI and Apache to serve your Laravel application, HTTP Basic authentication may not work correctly. To correct these problems, the following lines may be added to your application's .htaccess file:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Stateless HTTP Basic Authentication
You may also use HTTP Basic Authentication without setting a user identifier cookie in the session. This is primarily helpful if you choose to use HTTP Authentication to authenticate requests to your application's API. To accomplish this, define a middleware that calls the onceBasic method. If no response is returned by the onceBasic method, the request may be passed further into the application:
<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
class AuthenticateOnceWithBasicAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, $next)
{
return Auth::onceBasic() ?: $next($request);
}
}
Next, register the route middleware and attach it to a route:
Route::get('/api/user', function () {
// Only authenticated users may access this route...
})->middleware('auth.basic.once');
Logging Out
To manually log users out of your application, you may use the logout method provided by the Auth facade. This will remove the authentication information from the user's session so that subsequent requests are not authenticated.
In addition to calling the logout method, it is recommended that you invalidate the user's session and regenerate their CSRF token. After logging the user out, you would typically redirect the user to the root of your application:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
Invalidating Sessions On Other Devices
Laravel also provides a mechanism for invalidating and "logging out" a user's sessions that are active on other devices without invalidating the session on their current device. This feature is typically utilized when a user is changing or updating their password and you would like to invalidate sessions on other devices while keeping the current device authenticated.
Before getting started, you should make sure that the Illuminate\Session\Middleware\AuthenticateSession middleware is included on the routes that should receive session authentication. Typically, you should place this middleware on a route group definition so that it can be applied to the majority of your application's routes. By default, the AuthenticateSession middleware may be attached to a route using the auth.session route middleware key as defined in your application's HTTP kernel:
Route::middleware(['auth', 'auth.session'])->group(function () {
Route::get('/', function () {
// ...
});
});
Then, you may use the logoutOtherDevices method provided by the Auth facade. This method requires the user to confirm their current password, which your application should accept through an input form:
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($currentPassword);
When the logoutOtherDevices method is invoked, the user's other sessions will be invalidated entirely, meaning they will be "logged out" of all guards they were previously authenticated by.
Password Confirmation
While building your application, you may occasionally have actions that should require the user to confirm their password before the action is performed or before the user is redirected to a sensitive area of the application. Laravel includes built-in middleware to make this process a breeze. Implementing this feature will require you to define two routes: one route to display a view asking the user to confirm their password and another route to confirm that the password is valid and redirect the user to their intended destination.
The following documentation discusses how to integrate with Laravel's password confirmation features directly; however, if you would like to get started more quickly, the Laravel application starter kits include support for this feature!
Configuration
After confirming their password, a user will not be asked to confirm their password again for three hours. However, you may configure the length of time before the user is re-prompted for their password by changing the value of the password_timeout configuration value within your **application's config/auth.php **configuration file.
Routing
The Password Confirmation Form
First, we will define a route to display a view that requests the user to confirm their password:
Route::get('/confirm-password', function () {
return view('auth.confirm-password');
})->middleware('auth')->name('password.confirm');
As you might expect, the view that is returned by this route should have a form containing a password field. In addition, feel free to include text within the view that explains that the user is entering a protected area of the application and must confirm their password.
Confirming The Password
Next, we will define a route that will handle the form request from the "confirm password" view. This route will be responsible for validating the password and redirecting the user to their intended destination:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Redirect;
Route::post('/confirm-password', function (Request $request) {
if (! Hash::check($request->password, $request->user()->password)) {
return back()->withErrors([
'password' => ['The provided password does not match our records.']
]);
}
$request->session()->passwordConfirmed();
return redirect()->intended();
})->middleware(['auth', 'throttle:6,1']);
Before moving on, let's examine this route in more detail. First, the request's password field is determined to actually match the authenticated user's password. If the password is valid, we need to inform Laravel's session that the user has confirmed their password. The passwordConfirmed method will set a timestamp in the user's session that Laravel can use to determine when the user last confirmed their password. Finally, we can redirect the user to their intended destination.
Protecting Routes
You should ensure that any route that performs an action which requires recent password confirmation is assigned the password.confirm middleware. This middleware is included with the default installation of Laravel and will automatically store the user's intended destination in the session so that the user may be redirected to that location after confirming their password. After storing the user's intended destination in the session, the middleware will redirect the user to the password.confirm named route:
Route::get('/settings', function () {
// ...
})->middleware(['password.confirm']);
Route::post('/settings', function () {
// ...
})->middleware(['password.confirm']);
Adding Custom Guards
You may define your own authentication guards using the extend method on the Auth facade. You should place your call to the extend method within a service provider. Since Laravel already ships with an AuthServiceProvider, we can place the code in that provider:
<?php
namespace App\Providers;
use App\Services\Auth\JwtGuard;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::extend('jwt', function ($app, $name, array $config) {
// Return an instance of Illuminate\Contracts\Auth\Guard...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
}
As you can see in the example above, the callback passed to the extend method should return an implementation of Illuminate\Contracts\Auth\Guard. This interface contains a few methods you will need to implement to define a custom guard. Once your custom guard has been defined, you may reference the guard in the guards configuration of your auth.php configuration file:
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Closure Request Guards
The simplest way to implement a custom, HTTP request based authentication system is by using the Auth::viaRequest method. This method allows you to quickly define your authentication process using a single closure.
To get started, call the Auth::viaRequest method within the boot method of your AuthServiceProvider. The viaRequest method accepts an authentication driver name as its first argument. This name can be any string that describes your custom guard. The second argument passed to the method should be a closure that receives the incoming HTTP request and returns a user instance or, if authentication fails, null:
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::viaRequest('custom-token', function (Request $request) {
return User::where('token', $request->token)->first();
});
}
Once your custom authentication driver has been defined, you may configure it as a driver within the guards configuration of your auth.php configuration file:
'guards' => [
'api' => [
'driver' => 'custom-token',
],
],
Adding Custom User Providers
If you are not using a traditional relational database to store your users, you will need to extend Laravel with your own authentication user provider. We will use the provider method on the Auth facade to define a custom user provider. The user provider resolver should return an implementation of
Illuminate\Contracts\Auth\UserProvider:
<?php
namespace App\Providers;
use App\Extensions\MongoUserProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('mongo', function ($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new MongoUserProvider($app->make('mongo.connection'));
});
}
}
After you have registered the provider using the provider method, you may switch to the new user provider in your auth.php configuration file. First, define a provider that uses your new driver:
'providers' => [
'users' => [
'driver' => 'mongo',
],
],
Finally, you may reference this provider in your guards configuration:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
The User Provider Contract
Illuminate\Contracts\Auth\UserProvider implementations are responsible for fetching an Illuminate\Contracts\Auth\Authenticatable implementation out of a persistent storage system, such as MySQL, MongoDB, etc. These two interfaces allow the Laravel authentication mechanisms to continue functioning regardless of how the user data is stored or what type of class is used to represent the authenticated user:
Let's take a look at the Illuminate\Contracts\Auth\UserProvider contract:
<?php
namespace Illuminate\Contracts\Auth;
interface UserProvider
{
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}
The retrieveById function typically receives a key representing the user, such as an auto-incrementing ID from a MySQL database. The Authenticatable implementation matching the ID should be retrieved and returned by the method.
The retrieveByToken function retrieves a user by their unique $identifier and "remember me" $token, typically stored in a database column like remember_token. As with the previous method, the Authenticatable implementation with a matching token value should be returned by this method.
The updateRememberToken method updates the $user instance's remember_token with the new $token. A fresh token is assigned to users on a successful "remember me" authentication attempt or when the user is logging out.
The retrieveByCredentials method receives the array of credentials passed to the Auth::attempt method when attempting to authenticate with an application. The method should then "query" the underlying persistent storage for the user matching those credentials. Typically, this method will run a query with a "where" condition that searches for a user record with a "username" matching the value of $credentials['username']. The method should return an implementation of Authenticatable. This method should not attempt to do any password validation or authentication.
The validateCredentials method should compare the given $user with the $credentials to authenticate the user. For example, this method will typically use the Hash::check method to compare the value of $user->getAuthPassword() to the value of $credentials['password']. This method should return true or false indicating whether the password is valid.
The Authenticatable Contract
Now that we have explored each of the methods on the UserProvider, let's take a look at the Authenticatable contract. Remember, user providers should return implementations of this interface from the retrieveById, retrieveByToken, and retrieveByCredentials methods:
<?php
namespace Illuminate\Contracts\Auth;
interface Authenticatable
{
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}
This interface is simple. The getAuthIdentifierName method should return the name of the "primary key" field of the user and the getAuthIdentifier method should return the "primary key" of the user. When using a MySQL back-end, this would likely be the auto-incrementing primary key assigned to the user record. The getAuthPassword method should return the user's hashed password.
This interface allows the authentication system to work with any "user" class, regardless of what ORM or storage abstraction layer you are using. By default, Laravel includes a App\Models\User class in the app/Models directory which implements this interface.
Events
Laravel dispatches a variety of events during the authentication process. You may attach listeners to these events in your EventServiceProvider:
/**
- The event listener mappings for the application. *
- @var array */
protected $listen = [
'Illuminate\Auth\Events\Registered' => [
'App\Listeners\LogRegisteredUser',
],
'Illuminate\Auth\Events\Attempting' => [
'App\Listeners\LogAuthenticationAttempt',
],
'Illuminate\Auth\Events\Authenticated' => [
'App\Listeners\LogAuthenticated',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
'Illuminate\Auth\Events\Failed' => [
'App\Listeners\LogFailedLogin',
],
'Illuminate\Auth\Events\Validated' => [
'App\Listeners\LogValidated',
],
'Illuminate\Auth\Events\Verified' => [
'App\Listeners\LogVerified',
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogSuccessfulLogout',
],
'Illuminate\Auth\Events\CurrentDeviceLogout' => [
'App\Listeners\LogCurrentDeviceLogout',
],
'Illuminate\Auth\Events\OtherDeviceLogout' => [
'App\Listeners\LogOtherDeviceLogout',
],
'Illuminate\Auth\Events\Lockout' => [
'App\Listeners\LogLockout',
],
'Illuminate\Auth\Events\PasswordReset' => [
'App\Listeners\LogPasswordReset',
],
];
Practical Example
public function login(Request $request)
{
log::info('data aata hai');
log::info($request);
$flag = \Auth::attempt ([
'email' => $request->get ( 'email' ),
'password' => $request->get ( 'password' )
]);
if ($flag)
{
return redirect()->route('touroperator.dashboard');
}
}
public function postLogin(Request $request)
{
$credentials = [
'username' => $request['username'],
'password' => $request['password'],
];
// Dump data
dd($credentials);
if (Auth::attempt($credentials)) {
return redirect()->route('dashboard');
}
return 'Failure';
}
public function postRegister(Request $request)
{
// Retrieve all request data including username, email & password.
// I assume that the data IS validated.
$input = $request->all();
// Hash the password
$input['password'] = bcrypt($input['password']);
// Create the user
User::create($input);
// Redirect
return redirect()
// To the route named `login`
->route('login')
// And flash the request data into the session,
// if you flash the `$input` into the session, you'll
// get a "Failure" message again. That's because the
// password in the $input array is already hashed and
// the attempt() method requires user's password, not
// the hashed copy of it.
//
->with($request->only('username', 'password'));
}
public function postLogin(Request $request)
{
// Create the array using the values from the session
$credentials = [
'username' => session('username'),
'password' => session('password'),
];
// Attempt to login the user
if (Auth::attempt($credentials)) {
return redirect()->route('dashboard');
}
return 'Failure';
}
public function postRegister(Request $request)
{
$input = $request->all();
$input['password'] = bcrypt($input['password']);
User::create($input);
// event(UserWasCreated::class);
if (Auth::attempt($request->only('username', 'password'))) {
return redirect()
->route('dashboard')
->with('Welcome! Your account has been successfully created!');
}
// Redirect
return redirect()
// To the previous page (probably the one generated by a `getRegister` method)
->back()
// And with the input data (so that the form will get populated again)
->withInput();
}
Top comments (0)