Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel - Package can't recognise Auth functions?

I made a package which is counting the visitors on a webpage. Currently I have a single route, controller and view which don't do very much other than display a simple string. I have a separate Laravel application where this package is specifically build for. In this separate application I have a layout file called backend.

layouts/layouts/backend.blade.php.

My package view is extending this template like so: (backend.blade.php does not exists in the package but in the separate laravel application of-course)

@extends('layouts.layouts.backend')

@section('content')
    <div class="container-fluid pt-5 ">
        <div class="row">
            <div class="col-md-6">
                <h3>{{ __('Visitors') }}</h3>
            </div>
        </div>
    </div>
@endsection

The package successfully extends this layout but it can't find functions such as Auth::user()->token and it will say

Trying to get property 'token' of non-object (View: /Users/rainierlaan/Sites/rainierlaan/resources/views/layouts/layouts/backend.blade.php)

Why does this happen?

This is my packages service provider

 public function register()
    {
        // Controllers
        $this->app->make('Rainieren\Visitors\Http\Controllers\VisitorController');
        // Views
        $this->loadViewsFrom(__DIR__.'/resources/views', 'visitors');
        $this->publishes([
            __DIR__.'/resources/views' => resource_path('views/visitors'),
        ]);
        // Migrations
        $this->loadMigrationsFrom(__DIR__.'/database/migrations');
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        include __DIR__ . '/routes/routes.php';
    }

When I do vendor:publish the view successfully publishes to the right folder but somehow can't recognise functions such as Auth::user()->token or Auth::user()->unreadNotifications->count())

This is my package route:

<?php


Route::get('dashboard/visitors', '\Rainieren\Visitors\Http\Controllers\VisitorController@index')->name('visitors');

And this is the controller

public function index()
    {
        return view('visitors::index'); 
    }
like image 294
Rainier laan Avatar asked Feb 18 '20 14:02

Rainier laan


People also ask

What are AUTH and session facades in Laravel?

Laravel includes built-in authentication and session services which are typically accessed via the Auth and Session facades. These features provide cookie-based authentication for requests that are initiated from web browsers. They provide methods that allow you to verify a user's credentials and authenticate the user.

Why is HTTP Basic authentication not working in my Laravel application?

By default, the auth.basic middleware will assume the email column on your users database table is the user's "username". If you are using PHP FastCGI and Apache to serve your Laravel application, HTTP Basic authentication may not work correctly.

What are the different Laravel authentication packages?

These packages are Laravel Breeze, Laravel Jetstream, and Laravel Fortify. Laravel Breeze is a simple, minimal implementation of all of Laravel's authentication features, including login, registration, password reset, email verification, and password confirmation.

When should I use Laravel sanctum for authentication?

In general, Sanctum should be preferred when possible since it is a simple, complete solution for API authentication, SPA authentication, and mobile authentication, including support for "scopes" or "abilities". If you are building a single-page application (SPA) that will be powered by a Laravel backend, you should use Laravel Sanctum.


2 Answers

I would need a little bit more debugging information but my first assumption is the missing AuthenticateSession or Authenticate middleware.

Laravel defines a default middleware group web for your routes inside routes/web.php and this group uses the AuthenticateSession middleware. This is how a new installation looks like:

Route::group([
    'middleware' => 'web', <<< this is the magic part
    'namespace' => $this->namespace,
], function ($router) {
    require base_path('routes/web.php');
});

Here we see that the middleware group web is used.

In your custom module / service provider this is not the case. Your Route::get() definition is added to the Router but not inside this group. Therefore all necessary internals to authenticate the user are not performed.

In this scenario I would try to use ->middleware('auth') or ->middleware('web') which will use the main-projects group middleware.

Route::get('dashboard/visitors', '\Rainieren\Visitors\Http\Controllers\VisitorController@index')
  ->name('visitors')
  ->middleware('web');

Here is a different idea:

If you say you're always authenticated. Then you could try to move all web middlewares into the global middlewares within your Kernel (protected $middleware = []).

I did not tested this but I can imagine that this could work as well.

like image 132
Christoph Kluge Avatar answered Sep 21 '22 14:09

Christoph Kluge


I have seen in all of my active packages that they don't use Auth class at all in the views.

Their workaround is using this in the controller and pass it to the view:

$user = auth()->user();

return view('folder.view' ,['user'=>$user]);

And then in the view:

{{$user->token}} <!-- OR --!> {{$user->unreadNotifications->count()}}

Obviously as @N69S has stated only if a user is authenticated this is going to work.

Hope this works!!

EDIT:(Sorry didn't understand well the first time)

The error is in your service provider class yo have to do all the logic on the boot function, not in the register, because if you do in the register function, you load all before the laravel framework (To say something) https://laravel.com/docs/5.7/providers#the-register-method

Your serviceprovider should end like this:

    public function register()
    {
        //Nothing
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        // Controllers
        $this->app->make('Rainieren\Visitors\Http\Controllers\VisitorController');
        // Views
        $this->loadViewsFrom(__DIR__.'/resources/views', 'visitors');
        $this->publishes([
            __DIR__.'/resources/views' => resource_path('views/visitors'),
        ]);
        // Migrations
        $this->loadMigrationsFrom(__DIR__.'/database/migrations');
        include __DIR__ . '/routes/routes.php';
    }

Hope this finally works!

like image 44
ItsEdgar94 Avatar answered Sep 22 '22 14:09

ItsEdgar94