使用' auth'具有子域名的中间件

时间:2017-04-24 19:33:43

标签: laravel authentication routes subdomain middleware

我试图通过auth中间件在我的Controller中传递某些功能。但是,与这些函数关联的路由需要URL中的子域才能工作。这些功能似乎在它们不通过中间件或通过定制的中间件传递时起作用,但是' auth'中间件抛出错误:

UrlGenerationException.php第17行中的

UrlGenerationException: 缺少[Route:login] [URI:login]。

所需的参数

这类似于当我尝试在参数列表中运行没有$ account变量的函数时抛出的错误(因为它期望带有路径的子域)。

深入研究“认证”中正在调用的“认证”类。中间件,我发现导致错误的行是在public function authenticate(array $ guards)中,如下所示。

protected function authenticate(array $guards)

{
    if (empty($guards)) {
        /** ANYTHING BEFORE THIS RETURN STATEMENT RUNS WITH NO ERRORS **/
        return $this->auth->authenticate();
    }

    foreach ($guards as $guard) {
        if ($this->auth->guard($guard)->check()) {
            return $this->auth->shouldUse($guard);
        }
    }

    throw new AuthenticationException('Unauthenticated.', $guards);
}

以下是我的一些代码供参考(仅包含代码的相关摘要):

路由文件

路由\ web.php

Route::group(['domain' => '{account}.'.env('APP_URL')], function () {
  include('appRoutes/bcm.php');
});

路由\ appRoutes \ bcm.php

/********************************************/
/*********STATIC PAGE ROUTES******************/
/********************************************/

Route::get('/boards-commissions', 'BCM\PagesController@home');


/********************************************/
/*********BOARD ROUTES***********************/
/********************************************/

Route::get('/boards-commissions/boards', 'BCM\BoardsController@index');

Route::get('/boards-commissions/boards/archive/index', 
'BCM\BoardsController@archiveIndex');

控制器

应用\ HTTP \控制器\ BCM \ BoardsController.php

namespace App\Http\Controllers\BCM;

use Auth;
use Session;
use Validator;

use Illuminate\Http\Request;
use Illuminate\Foundation\Validation\ValidatesRequests;

//Models
use App\Models\BCM\Board;

class BoardsController extends Controller
{
    public function __construct()
    {
        $this->middleware('bcm_app_access');
        $this->middleware('auth', ['except' => array('index', 'show')]);
        $this->middleware('bcm_admin', ['only' => array('edit', 'update', 
'create', 'store', 'archive', 'showArchive', 'showArchivedBoard', 'restore')]);
    }

    public function index($account, Request $request) {
        $boards = Board::all();
        $user = $request->user();
        return view('bcm.boards.index')->with('boards', $boards)->with('user', $user);
    }

    public function archiveIndex($account, Request $request) {
        $boards = Board::all();
        $user = $request->user();
        return view('bcm.boards.archiveList')->with('boards', $boards)->with('user', $user);
    }
}

似乎只有auth中间件到目前为止还没有工作。索引函数运行得很好(因为它被排除在控制器结构中的auth中间件之外),即使它正在通过bcm_app_access中间件传递。但是当archiveIndex通过auth中间件时会抛出上面提到的UrlGenerationException错误。

我有一种感觉,$ account参数需要添加或包含在某处,以便auth中间件知道它需要引用它,但我不知道在哪里添加它并且我不知道'知道在$ this-> auth-> authenticate()时引用了哪些其他文件;是运行所以我不知道在哪里添加它。任何想法?

3 个答案:

答案 0 :(得分:1)

在最初的问题中,我想知道如何让'auth'中间件与子域一起使用。我仍然没有想到这样做,但我已经通过创建一个基本的自定义中间件建立了功能性的解决方案。验证中间件的要点是检查站点的用户是否已登录或作为guest虚拟机运行。为了模仿这个功能,我通过运行

创建了一个中间件
php artisan make:middleware SubdomainAuth

在命令行中。然后我将自动生成的中间件文件配置为如下所示:

<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
class SubdomainAuth
{
    /**
     * Handle an incoming request to make sure that a valid user is logged in.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next) {
        $user = Auth::user();
        if ($user == null) {
          return redirect('/login');
        }
        return $next($request);
    }
}

最后,我通过添加行

将我的内核配置为识别新的中间件
'sub_auth' => \App\Http\Middleware\SubdomainAuth::class,

到app / Http / Kernel.php。从那里我能够用我创建的sub_auth中间件替换控制器中的auth中间件。我上面问题的例子现在看起来像这样:

namespace App\Http\Controllers\BCM;

use Auth;
use Session;
use Validator;

use Illuminate\Http\Request;
use Illuminate\Foundation\Validation\ValidatesRequests;

//Models
use App\Models\BCM\Board;

class BoardsController extends Controller
{
    public function __construct()
    {
        $this->middleware('bcm_app_access');
        $this->middleware('sub_auth', ['except' => array('index', 'show')]);
        $this->middleware('bcm_admin', ['only' => array('edit', 'update', 
'create', 'store', 'archive', 'showArchive', 'showArchivedBoard', 'restore')]);
    }

    public function index($account, Request $request) {
        $boards = Board::all();
        $user = $request->user();
        return view('bcm.boards.index')->with('boards', $boards)->with('user', $user);
    }

    public function archiveIndex($account, Request $request) {
        $boards = Board::all();
        $user = $request->user();
        return view('bcm.boards.archiveList')->with('boards', $boards)->with('user', $user);
    }
}

此解决方法成功筛选未登录的用户并将其重定向到登录页面。但是,我不熟悉Authenticate中间件如何工作以了解我创建的SubdomainAuth类中是否缺少我的自定义类所增加的安全性。

答案 1 :(得分:1)

laravel7入门指南

您的子域的通配符参数sort_by

{brand}

将在Route::domain( '{brand}.' . parse_url(config('app.url'), PHP_URL_HOST) )->group(function () { // login page Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login')->middleware('guest'); Route::middleware('auth')->group(function () { Route::get('/', 'BrandController@showDashboard')->name('dashboard'); ... } }); 对象中访问,因此在以下位置:

$request

只需将通配符作为参数传递给路由功能

答案 2 :(得分:0)

我遇到了同样的问题。这是我的解决方案:

Laravel的Auth Middleware使用默认路由('login')来处理它 \照亮\基金会\例外\ Handler.php

Limit Exceeded: Email Body Size.

您可以在此处修改以更改路线('登录','子域')以使其正常工作。但就个人而言,我想保持框架不受影响。我修改了Exceptions Handler而不是覆盖“ unauthenticated ”函数。

在\ app \ Exceptions \ Handler.php

中添加新功能
protected function unauthenticated($request, AuthenticationException $exception)
{
    return $request->expectsJson()
                ? response()->json(['message' => $exception->getMessage()], 401)
                : redirect()->guest(route('login'));
}

我使用$ request获取url并将其解压缩。我想如果你可以深入研究 userResolver ,你就可以提取你在routes / web.php中定义的子域变量,但我现在对此很满意。