Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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