Solucionado (ver solução)
Solucionado
(ver solução)
13
respostas

Middleware sempre redirecionando para o login

Olá, estou usando a versão 5.3 do Laravel.

Seguindo a aula de autenticação, tudo funciona, até que faço a parte do middleware.

O que acontece é que eu faço o login e ele dá certo:

aparece o "Usuário logado com sucesso" no http://localhost:8000/login

porém, quando eu tento ir para outro lugar, por exemplo a listagem de produtos (http://localhost:8000/) eu sou novamente redirecionado para o form de login...

Meu middleware:

public function handle($request, Closure $next)
    {
        if (!$request->is('login') && Auth::guest()) {
            return redirect('/login');
        }
        return $next($request);
    }

Meu Kernel:

protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\Autorizador::class,
    ];

LoginController:

public function form () {
        return view('form_login');
    }

    public function login () {
        // Credenciais (email e senha)
        $credenciais = Request::only('email', 'password');

        // Login
        if (Auth::attempt($credenciais)) { 
            return 'Usuário logado com sucesso';
        }
        else {
            return 'Usuário não existe';
        }

    }

Meu método do ProdutoController que lista todos os produtos:

public function lista()
        {
            if (Auth::guest()) { 
                return redirect('/login');
            }

            $produtos = Produto::all();

            return view('produto/listagem')->with('produtos', $produtos);
        }

Fiz algo errado ou é algo com a versão 5.3 mesmo?

13 respostas

Se você fez o middleware coloca no construtor do ProdutoController

public function __construct(){
        $this->middleware('autorizador');
    }

Ele já vai fazer isso para você.

Bem, realmente tinha esquecido de add o construtor no meu ProdutoController...

porém mesmo arrumando isso, continuo com o mesmo problema!

Após me logar, aparece a mensagem que fez login com sucesso, inclusive mostrando o nome do usuário logado:

"Usuário José Guilherme logado com sucesso"

Porém quando eu tento acessar outra página, por exemplo a lista de produtos, eu sou direcionado para o login novamente.

Coloquei um dd(Auth::guest()); no middleware depois de aparecer a mensagem de logado com sucesso, e quando vou acessar outra página, cai de novo na página de login falando que o Auth:guest() é true, como se n"ao estivesse guardando que já estou logado...

Alguma sugestão?

Oi José

pode mostrar como está o código do seu middleware e o trecho que você adicionou ele no Kernel?

Rodrigo, segue:

Middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Auth;

class Autorizador
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next) 
    {
        if (!$request->is('login') && Auth::guest()) {
            return redirect('/login');
        }
        return $next($request);
    }
}

Kernel:

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\Autorizador::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

Oi José

Se você tirar o if (Auth::guest()) do método do controller, o comportamento é o mesmo? O middleware já faz esse trabalho pra você, pra não ter que espalhar esses ifs.

Resolvendo a questão do if, se você colocar um "echo qualquercoisa", ele imprime? Pra sabermos se ele realmente está passando pelo seu autorizador.

Oi Rodrigo, mesmo sem o if... do ProdutoController isso acontece.

Coloquei um echo dentro do meu autorizador para verificar se está passando pelo autorizador

public function handle($request, Closure $next) // next é o código que será executado em seguida
    {
        echo "autorizador fora do if";

  if (!$request->is('login') && Auth::guest()) {
            echo "autorizador dentro do if";
            return redirect('/login');
        }
        return $next($request);
    }

Apareceu a mensagem "autorizador fora do if" na página de login

Oi José

Então sabemos a causa, agora precisamos entender o porque não está entrando no if.

Tenta isolar as condicionais pra ver qual falha? Isto é, mande imprimir o !$request->is('login') e também o Auth::guest() pra ver qual retorna false, assim saberemos a condição que não está sendo atendida.

A URL é apenas login mesmo? De acordo com a versão que você estiver usando, ou da forma que você mapeou no arquivo de rotas, o ela pode ser diferente. Na versão que utilizei para gravar o curso, por exemplo, era "auth/login".

if(!$request->is('auth/login') && \Auth::guest()) {
    return redirect('/auth/login');
}
solução!

O problema ocorre com o guest mesmo...

Ele retorna como true.

Quanto ao caminho, no meu caso é só "/login" mesmo.

Pesquisando mais na internet, me foi sugerido que registrasse o middleware no $routeMiddleware ao invés do $middleware ficando assim...

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'autorizador' => \App\Http\Middleware\Autorizador::class,
    ];
}

fiz isso, e aparentemente funciona agora, porém não fiz muitos testes!

Alguma ideia do porque disso?

Quanto ao método passado na aula, pode ser algum problema com o meu DB?

Acho que a diferença é que agora você passa o nome 'autorizador' junto com o middleware, e antes você não passava, certo?

Rodrigo, correto.

Maravilha! Então agora está tudo funcionando?

Está sim Rodrigo.

Mais uma coisa, tem como colocar o arquivo final do projeto naquela página do github?

Seria bom para poder dar uma olhada quando surgisse alguma dúvida, antes de ter de usar o fórum...

Obrigado pela ajuda

Oi José!

Pensei que o projeto já estava no GitHub, muito obrigado pelo aviso!

Vou pedir para os nossos moderadores

um abraço