expand_less

Authentication

Introduction

Many web applications provide a means for users to authenticate themselves. Implementing this functionality from scratch can be complex and may lead to security vulnerabilities. Dreamfork offers mechanisms to streamline the authentication process.

Authentication in Dreamfork operates on the principles of providers and guards. Guards define how user authentication is performed, while providers specify what constitutes a user for authentication purposes. Dreamfork provides ORM (Object-Relational Mapping) and database query builder, which are utilized in providers.

Configuration

The configuration for authentication in Dreamfork can be found in the file /config/auth.php. Each option available there is thoroughly documented. For example, if you wish to refer to individuals using your application differently than as "users," you can change the model of the provider.

                                
                                    
'providers' => [
'users' => [
'model' => App\Models\Client::class,
],
],

Authenticating Users

The process of authenticating users in Dreamfork is straightforward. To achieve this, the Auth facade is utilized. Once the facade is imported, the attempt method can be used to attempt a login. If the login is successful, a token can be generated for the user and returned. The attempt method requires passing the fields by which we want to authenticate the user, including the mandatory password field.

                                
                                    
use Framework\Support\Facades\Auth;
 
public function login($request) {
$credentials = $request->validate([
'login' => ['required'],
'password' => ['required'],
]);
 
if (Auth::attempt($credentials)) {
$token = Auth::user()->createToken('user');
return response()->json(['token' => $token->plainTextToken]);
}
}

The attempt method takes an array of key/value pairs as its first argument. The values in the array are used to locate the user in your database table. In the given example, the user is retrieved based on the value of the login column. If the user is found, the hashed password stored in the database is compared with the password value passed to the method via the array. It's important not to hash the incoming request's password value, as the framework will automatically hash the value before comparing it to the hashed password in the database. An authenticated session is initiated for the user if the two hashed passwords match.

It's worth noting that Dreamfork's authentication services retrieve users from your database based on your authentication guard's "provider" configuration. In the default configuration file /config/auth.php, the ORM user provider is specified, and it's instructed to use the App\Models\User model when retrieving users. You have the flexibility to modify these values within your configuration file to suit the requirements of your application.

The attempt method returns true if authentication was successful; otherwise, it returns false.

Specifying Additional Conditions

If desired, you can include additional query conditions in the authentication query along with the user's login and password. To achieve this, you can add the query conditions to the array passed to the attempt method. For instance, you might want to ensure that the user is marked as "active":

                                
                                    
use Framework\Support\Facades\Auth;
 
public function login($request) {
if (Auth::attempt(['login' => $login, 'password' => $password, 'active' => 1])) {
$token = Auth::user()->createToken('user');
return response()->json(['token' => $token->plainTextToken]);
}
}

Other Authentication Methods

Authenticate A User Instance

If you want to set an existing user instance as the currently authenticated user, you can achieve this by passing the user instance to the Auth facade's login method. The provided user instance must implement the Framework\Services\Auth\Token\Tokenable trait. The App\Models\User model, included with Dreamfork, already satisfies this interface. This authentication method is beneficial when you have a valid user instance, for example, immediately after a user registers with your application:

                                
                                    
use Framework\Support\Facades\Auth;
 
Auth::login($user);

Working With Authenticated User

Let's assume that in your application, which serves as a backend API, you have a login mechanism, and a user has already generated an authentication token. This token is then used to authenticate each API request. Now, you want to secure the /profile endpoint, which returns user data, allowing access only to authenticated users. To achieve this, you need to have protected route.

Protecting Routes

The protection of routes can be achieved by adding them to a guard. In this manner, access to these routes will only be permitted for authenticated users:

                                
                                    
Route::post('/login', [UserController::class, 'login']);
 
Route::guard(function() {
Route::get('/profile', [UserController::class, 'me']);
});

In this way, if someone attempts to access this endpoint without providing an authentication token, the guard will prevent the request from proceeding, returning appropriate information.

Retrieving The Authenticated User

Dreamfork provides various methods for retrieving the authenticated user. When handling a request sent to a guarded route, you can access the user using three different methods. You can use the Auth facade, the auth() helper function, or directly retrieve the user from the request. Each of these methods achieves the same result:

                                
                                    
public function me($request) {
$userWithFacade = Auth::user();
 
$userWithRequest = $request->user();
 
$userWithHelper = auth()->user();
}

If you want to retrieve only the ID of the authenticated user, you can use the id() method on the Auth facade or helper. Please note that the id() method is not available directly on the request object, as the request handles only the user() method among the authentication-related methods:

                                
                                
public function me($request) {
$userId = Auth::id(); // Will work
 
$userId = auth()->id(); // Will work
 
$userId = $request->id(); // Will not work
}

Determining If The Current User Is Authenticated

To check if the user making the incoming HTTP request is authenticated, you can use the check method on the Auth facade. This method will return true if the user is authenticated:

                                
                                    
if (Auth::check()) {
// The user is authenticated...
}

While it is indeed possible to determine whether a user is authenticated using the check method, it is more common to use a guard on route for verifying the user's authentication status before granting access to specific routes or controllers.