1
Q

What is an CSRF attack?

A

Cross-site request forgery attacks allow malicious site creators to input something in your application in the name of an authenticated user. For example, imagine if your application has a /user/email route that accepts a POST request to change the authenticated user’s email address. Most likely, this route expects an email input field to contain the email address the user would like to begin using. Without CSRF protection, a malicious website could create an HTML form that points to your application’s /user/email route and submits the malicious user’s own email address to take over the account of the user. If the malicious website automatically submits the form when the page is loaded, the malicious user only needs to lure an unsuspecting user of your application to visit their website and their email address will be changed in your application.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How does Laravel prevent CSRF attacks?

A

Laravel automatically generates a CSRF “token” for each active user session managed by your application. This token is used to verify that the authenticated user is the person actually making the requests to the application. Since this token is stored in the user’s session and changes each time the session is regenerated, a malicious application is unable to access it. The current session’s CSRF token cab be accessed via the request’s session or via the csrf_token helper function:

Route::get('/token', function (Request $request) {
    $token = $request->session()->token();
 
    $token = csrf_token();
 
    // ...
});
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Sometimes you may wish to exclude a set of URIs from CSRF protection, for example for processing payments. How can you exclude specific sites / applications from your CSRF protection?

A

You may exclude specific routes by providing their URIs to the validateCsrfTokens method in your application’s bootstrap/app.php file:

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'stripe/*',
        'http://example.com/example/*',
    ]);
});

This would now allow stripe and example.com/example/anything after the / to interact with your application.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

When using Laravel’s encrypter, you must set the key configuration option in your config/app.php configuration file. How can you use Artisan to generate keys for you?

A

php artisan key:generate

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What will happen if you change your applications encryption key and how can you prevent these things from becoming problems?

A

If you change your application’s encryption key, all authenticated user sessions will be logged out of your application. This is because every cookie, including session cookies, are encrypted by Laravel. In addition, it will no longer be possible to decrypt any data that was encrypted with your previous encryption key. To mitigate this issue, Laravel allows you to list your previous encryption keys in your application’s APP_PREVIOUS_KEYS environment variable. This variable may contain a comma-delimited list of all of your previous encryption keys. When you set this environment variable, Laravel will always use the “current” encryption key when encrypting values. However, when decrypting values, Laravel will first try the current key, and if decryption fails using the current key, Laravel will try all previous keys until one of the keys is able to decrypt the value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How can you encrypt a string?

A

You may encrypt a value using the encryptString method provided by the Crypt facade. All encrypted values are encrypted using OpenSSL and the AES-256-CBC cipher. Furthermore, all encrypted values are signed with a message authentication code (MAC). The integrated message authentication code will prevent the decryption of any values that have been tampered with by malicious users.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How can you decrypt a string and what happens, if the string couldn’t correctly be decrypted?

A

You may decrypt values using the decryptString method provided by the Crypt facade. If the value can not be properly decrypted, such as when the message authentication code is invalid, an Illuminate\Contracts\Encryption\DecryptException will be thrown.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

At its core, Laravel’s authentication facilities are made up of “guards” and “providers”. What do they do?

A

Guards define how users are authenticated for each request. For example, Laravel ships with a session guard which maintains state using session storage and cookies.
Providers define how users are retrieved from your persistent storage. Laravel ships with support for retrieving users using Eloquent and the database query builder. However, you are free to define additional providers as needed for your application.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Where is the application’s authentication configuration file located?

A

config/auth.php

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is Laravel Breeze?

A

Laravel Breeze is a simple, minimal implementation of all of Laravel’s authentication features, including login registration, password reset, email verification, and password confirmation. Laravel Breeze’s view layer is compromised of simple Blade templates styled with Tailwind CSS.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is Laravel Fortify?

A

Laravel Fortify is a headless authentication backend for Laravel that implements many features including cookie based authentication as well as two-factor authentication and email verification. Fortify provides the authentication backend for Laravel Jetstream or may be used independetly in combination with Laravel Sanctum to provide authentication for an SPA that needs to authenticate with Laravel.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is Laravel Jetstream?

A

Laravel Jetstream is a robust application starter kit that consumes and exposes Laravel Fortify’s authentication services with a beautiful, modern UI powered by Tailwind CSS, Livewire, and / or Inertia. Laravel Jetstream includes optional support for two-factor authentication, team support, browser session management, profile management, and built-in integration with Laravel Sanctum to offer API token authentication.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is Laravel Passport?

A

Passport is an OAuth2 authentication provider, offering a variety of OAuth2 “grant types” which allow you to issue various types of tokens. In general, this is a robust and complex package for API authentication. However, most applications do not require the complex features offered by the OAuth 2 spec, which can be confusing for both users and developers. In addition, developers have been historically confused about how to authenticate SPA applications or mobile applications using OAuth2 authentication providers like Passport.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

What is Laravel Sanctum?

A

Simpler, more streamlined authentication package, that could handle both first-party web requests from a web-browser and API requests via tokens. It’s a hybrid web / API authentication package that can manage your application’s entire authentication process. This is possible because when Sanctum based applications receive a request, Sanctum will first determine if the request includes a session cookie that references an authenticated session. Sanctum accomplishes this by calling Laravel’s built-in authentication services. If the request is not being authenticated via a session cookie, Sanctum will inspect the request for an API token. If an API token is present, Sanctum will authenticate the request using that token.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

After installing and using an authentication starter kit from Laravel and allowing users to register and authenticate your application, you will often need to interact with the currently authenticated user. How can you access the user while handling an incoming request?

A

By using the user method of the Auth facade, for example:

// 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, for example:

public function update(Request $request): RedirectResponse
{
    $user = $request->user();
...
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

How can you check if a user is logged in?

A

By using the check method of the Auth facade, for example:

if (Auth::check()) {
    // The user is logged in...
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

What do you need to do to make a route only accessible to logged in users?

A
Route::get('/example', function() {
    // Only authenticated users may access this route...
})->middleware('auth');
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

How can you redirect unauthenticated users to the login page if they try to access something, that guests are not supposed to access?

A
In bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
    $middleware->redirectGuestTo('/login');
})
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

How can you specify which guard should be used to authenticate a user?

A

You can specify the specific guard after a “:” after the auth middleware like this:

Route;;get('/example', function () {
    // Only authenticated users may access this route...
})->middleware('auth:admin');
20
Q

When manually authenticating a user, how can you add more extensive inspection of the potential user before actually authenticating the user? For example, how can you verify that the user isn’t banned before authenticating them?

A

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 them. For example:

if (Auth::attemptWhen([
    'email' => $email,
    'password' => $password,
], function (User $user) {
    return $user->isNotBanned();
})) {
    // Authentication was successful...
}
21
Q

How can you implement the functionality of a “remember me” button for a login while manually authenticating a user?

A

You may pass a boolean value as the second argument to the attempt method and 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:

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:

if (Auth::viaRemember()) {
    // ...
}
22
Q

How can you set an existing user instance as the currently authenticated user?

A

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. If needed, you may specify an authentication guard before calling the login method:
Auth::guard('admin')->login($user);

23
Q

What is HTTP Basic Authentication and how can you implement it?

A

HTTP Basic Authentication provides a quick way to authenticate users of your application without setting up a dedicated “login” page. To use it, 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');
24
Q

How can you manually log out of your application?

A

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:

public function logout(Request $request): RedirectResponse
{
    Auth::logout();

    $request->session()->invalidate();

    $request->session()->regenerateToken();

    return redirect('/');
}
25
Q

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. How can you do that?

A

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 middleware alias:

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:
Auth::logoutOtherDevices($currentPassword);

26
Q

Where do you need to define your own authentication guards to add them?

A

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 AppServiceProvider, we can place the code in that provider.

27
Q

How can you disable automatic password rehashing in your application?

A

First publish the hashing configuration file:
php artisan config:publish hashing

Once the configuration file has been published, you may set the rehash_on_login_ configuration value to false:
'rehash_on_login' => false,

28
Q

What are gates and policies in regards to authorization?

A

Laravel provides two primary ways of authorizing actions: gates and policies. Think of gates and policies like routes and controllers. Gates provide a simple, closure-based approach to authorization while policies, like controllers, group logic around a particular model or resource. You do not need to choose between exclusively using gates or exclusively using policies when building an application. Most applications will most likely contain some mixture of gates and policies, and that is perfectly fine! Gates are most applicable to actions that are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.

29
Q

Where should you define gates?

A

Gates are typically defined within the boot method of the App\Providers\AppServiceProvider class using the Gate facade. Gates always receive a user instance as their first argument and may optionally receive additional arguments such as a relevant Eloquent model:

Gate::define('update-post', function (User $user, Post $post) {
    return $user->id === $post->user_id;
});

Like controllers, gates may also be defined using a class callback array:
Gate::define('update-post', [PostPolicy::class, 'update']);

30
Q

How can you authenticate if a user is allowed to do something using the authorization of a gate?

A

To authorize an action using gates, you should use the allows or denies methods provided by the Gate facade. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate closure. It is typical to call the gate authorization methods within your application’s controllers before performing an action that requires authorization:

public function update(Request $request, Post $post): RedirectResponse
{
    if (! Gate::allows('update-post' $post)) {
        abort(403);
    }

    // Update the post in this example here

   return redirect('/posts');
}
31
Q

How can you determine if a user other than the currently authenticated user is authorized to perform an action?

A

By using the forUser method on the Gate facade:

if (Gate::forUser($user)->allows('update-post', $post)) {
    // The user can update the post...
}

if (Gate::forUser($user)->denies('update-post', $post)) {
    // The user can't update the post...
}
32
Q

How can you attempt to authorize an action and automatically throw an Illuminate\Auth\Access\AuthorizationException?

A
Gate::authorize('update-post', $post);

// The action is authorized
33
Q

What does giving the gate methods for authorizing abilities or the authorization Blade directives an array as the second argument do?

A

You can then include multiple things to be checked for the authorization, if multiple things need to be checked.

34
Q

Sometimes you may wish to return a more detailed response, including an error message. How can you achieve that?

A

To do so, you may return an Illuminate\Auth\Access\Response from your gate:

Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
        ? Response::allow()
        : Response::deny('You must be an administrator.');
});
35
Q

When an action is denied via a Gate, a 403 HTTP response is returned; however, it can sometimes be useful to return an alternative HTTP status code. How can you customize the status code returned for a failed authorization check and how can you specifically make it a 404 status code?

A

You may customize the HTTP status code returned for a failed authorization check using the denyWithStatus static constructor on the Illuminate\Auth\Access\Response class:

Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin
        ? Response::allow()
        : Response::denyWithStatus(123);
});

That would return the status code 123, you can obviously just input 404 there but if you want 404 to be returned you can also simply do this:
: Response::denyAsNotFound();

36
Q

How can you grant all abilities to a specific user?

A

You may use the before or after method to define a closure that is run before all other authorization checks:

Gate::before(function (User $user, string $ability) {
    if ($user->isAdministrator()) {
        return true;
    }
});
Gate::after(function (User $user, string $ability, bool|null $result, mixed $arguments) {
    if ($user->isAdministrator()) {
        return true;
    }
});

The result of either one of these would be considered the result of the authorization check if it returns anything else than null, otherwise the other test would be used.

37
Q

How can you create an inline authorization check, that does not require setting up a full on gate separately?

A

Laravel allows you to perform these types of “inline” authorization checks via the Gate::allowIf and Gate::denyIf methods. Inline authorization does not execute any defined “before” or “after” authorization hooks:

Gate:: allowIf(fn (User $user) => $user->isAdministrator());

Gate:: denyIf(fn (User $user) => $user->banned());

If the action is not authorized or if no user is currently authenticated, Laravel will automatically throw an Illuminate\Auth\Access\AuthorizationException exception. Instances of AuthorizationException are automatically converted to a 403 HTTP response by Laravel’s exception handler.

38
Q

Generate a policy!

A

php artisan make:policy ExamplePolicy

The make:policy command will generate an empty policy class. If you would like to generate a class with example policy methods related to viewing, creating, updating and deleting the resource, you may provide a –model option when executing the command:
php artisan make:policy ExamplePolicy –model=Example

39
Q

Where are policies stored and what naming convention should you follow with your policies?

A

By default, Laravel automatically discovers policies as long as the model and policy follow the standard Laravel naming conventions. Specifically, the policies must be in a Policies directory at or above the directory that contains your models. So, for example, the models may be placed in the app/Models directory while the policies may be placed in the app/Policies directory. In this situation, Laravel will check for policies in app/Models/policies then app/Policies. In addition, the policy name must match the model name and have a Policy suffix. So, a User model would correspond to a UserPolicy policy class.

40
Q

How can you manually register policies and their corresponding models?

A

Within the boot method of your application’s AppServiceProvider:

public function boot(): void
{
    Gate::policy(Example::class, ExamplePolicy::class);
}
41
Q

Create a method within a Policy class, that tests if a User $user is authorized to update a Post $post!

A
class PostPolicy
{
    public function update(User $user, Post $post): bool
    {
        return $user->id === $post->user_id;
    }
}
42
Q

Sometimes you may wish to give a more detailed response than the simple boolean that would be returned normally, how can you set up an error message for unauthorized accessing of things?

A

Within the method of your Policy class, you can return an Illuminate\Auth\Access\Response instance like so:

public function update(User $user, Post $post): Response
{
    return $user->id === $post->user_id
        ? Response::allow()
        : Response::deny('You do not own this post.');
}
43
Q

In your Policy class, how can you stop the authorization checks from being applied to certain users and instead either authorize them for everything or nothing?

A

To accomplish this, define a before method on the policy. The before method will be executed before any other methods on the policy, giving you an opportunity to authorize the action before the intended policy method is actually called. This feature is most commonly used for authorizing application administrators to perform any action:

public function before(User $user, string $ability): bool|null
{
    if ($user->isAdministrator()) {
        return true;
    }

    if ($user->banned()) {
        return false;
    }

    return null;
}

If you return true, then everything will be authorized, if you return false everything will be denied and if you return null then the actual checks for the different things are going to be applied. The before method of a policy class will not be called if the class doesn’t contain a method with a name matching the name of the ability being checked.

44
Q

Which methods does the User model include for authorization and how do they work?

A

The can and cannot methods receive the name of the action you wish to authorize and the relevant model. For example, let’s determine if a user is authorized to update a given App\Models\Post model. Typically, this will be done within a controller method:

public function update(Request $request, Post $post): RedirectResponse
{
    if ($request->user()->cannot('update', $post)) {
        abort(403);
    }

    // Update the post...

    return redirect('/posts');
}

If a policy is registered for the given model, the can method will automatically call the appropriate policy and return the boolean result. If no policy is registered for the model, the can method will attempt to call the closure-based Gate matching the given action name.

45
Q

How can you authorize actions before the incoming request even reaches your routes or controllers?

A

By using a middleware! The Illuminate\Auth\Middleware\Authorize middleware may be attached to a route using the can middleware alias, which is automatically registered by Laravel. For example:

Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');

In this example, we’re passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method. in this case, since we are using implicit model binding, an App\Models\Post model will be passed to the policy method. If the user is not authorized to perform the given action, an HTTP response with a 403 status code will be returned by the middleware. For convenience, you can also attach the can middleware to your route using the can method:
Route:: … })->can(‘update’, ‘post’);

46
Q

When writing Blade templates, you may wish to display a portion of the page only if the user is authorized to perform a given action. For example, you may wish to show an update form for a blog post only if the user can actually update the post. Which blade directives can you use for that?

A
@can and @cannot:

@can('update', $post)
    <!-- The current user can update the post... -->
@elsecan('create', App\Models\Post::class)
    <!-- The current user can create new posts... -->
@else
    <!-- ... -->
@endcan

@cannot('update', $post)
    <!-- The current user cannot update the post... ->
@elsecannot('create', App\Models\Post::class)
    <!-- The current user cannot create new posts... -->
@endcannot