0

类型错误:传递给 App\Http\Middleware\UserAuthMiddleware::handle() 的参数 3 必须实现接口 App\Contracts\UserAuth,没有给出,在 C:\wamp64\www\laravel\vendor\laravel\framework\src\ 中调用Illuminate\Pipeline\Pipeline.php 在第 148 行

我从中间件内部得到了这个错误,但是当我在我的控制器中使用给定的合同时,它工作得很好。有谁知道发生了什么?

中间件文件

namespace App\Http\Middleware;

use Closure;
use App\Contracts\UserAuth;

class UserAuthMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, UserAuth $user)
    {
        return $next($request);
    }
}

UserAuth 服务文件

<?php

namespace App\Services;
use App\UsersModel;

class UserAuth implements \App\Contracts\UserAuth
{
    public $username;
    public $password;
    public $perm_level = "admin";
    public $guest = true;

    public function load()
    {
        if (session()->has("user"))
        {
            $user = UserModel::where([
                "username" => session("user"),
                "password" => session("password")
            ])->first();
            $this->username = $user->username;
            $this->password = $user->password;
            $this->guest = false;
        }
    }

    public function isLogged()
    {
        return $this->guest;
    }
}

AppServiceProvider 注册

public function register()
{
    $this->app->singleton(\App\Contracts\UserAuth::class, \App\Services\UserAuth::class);
}

路线

//REGISTRATION ROUTES
Route::get("/register", "User@register")->middleware("user_auth");
Route::post("/register", "User@save_user")->middleware("user_auth");

有工作合同的用户控制器

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\UsersModel;
use App\Contracts\UserAuth;

class User extends Controller
{
    public function register(Request $request, UserAuth $user)
    {
        return view("registration.form", ["request" => $request]);
    }

    public function login(Request $request)
    {
        $user = UsersModel::where([
            "username" => $request->username,
            "password" => $request->password
        ])->first();
        if ($user) 
        {
            session(["user" => $user->username, "password" => $user->password]);
            return back();
        }
        else return back()->with("login_attempt", "failed");
    }

    public function logout()
    {
        session()->forget("user", "password");
        return back();
    }

    public function save_user(Request $request)
    {
        $errors = [];

        //Data validation
        $input = $request->all();

        if ( in_array(null, $input) ) 
            $errors["empty_fields"] = true;

        if ( !preg_match("/[A-Za-z0-9 ]{3,16}/", $input["username"]) ) 
            $errors["invalid_username"] = true;

        if ( $input["password"] != $input["password_confirm"] ) 
            $errors["unmatching_passwords"] = true;

        if ( !preg_match("/[A-Za-z0-9\-\.]{3,16}@[A-Za-z0-9](\.[a-z0-9]){1,2}/", $input["email"]) ) 
            $errors["invalid_email"] = true;

        if ( UsersModel::where("username", $input["username"])->first() ) 
            $errors["username_taken"] = true;

        if (count($errors) > 0) return view("registration.form", ["err" => $errors, "request" => $request]);
        else return view("registration.save", ["request" => $request]);
    }
}
4

1 回答 1

0

您错误地尝试将临时参数传递给中间件参数中的句柄函数。

当你定义这个时:

public function handle($request, Closure $next, UserAuth $user)

这意味着中间件期望在其中传递一个参数,它不会来自 DI 容器,因此 $user 变量为空,未能通过类型提示约束。

此处允许的参数仅适用于“角色”,您不能传递随机的东西并期望 DI 容器来解决它。

我建议你尝试这样的事情:

public function handle($request, Closure $next)
{
    if($request->user()->isLogged()) {
        return $next($request);
    } else {
        return redirect('login'); // or whatever route
    }
}

为此,您需要将isLogged函数定义为 Trait 的一部分,并将其添加到App\User模型中。

请参见:

https://laracasts.com/discuss/channels/laravel/pass-variable-from-route-to-middleware

https://laravel.com/docs/5.4/middleware#middleware-parameters

于 2017-07-26T10:18:20.597 回答