【问题标题】:Sharing same route with unauthenticated and authenticated users in Laravel 5.3在 Laravel 5.3 中与未经身份验证和经过身份验证的用户共享相同的路由
【发布时间】:2017-01-28 08:10:54
【问题描述】:

我有一条使用身份验证中间件的路线,效果很好。

Route::group(['prefix' => 'v1','middleware' => ['auth:api']], function()
{
  Route::resource('user', 'v1\MyController');
});

问题是我还希望未经身份验证的用户也可以访问此路由。使用上述内容,我收到 401 Unauthorized 错误,我无法为未经身份验证的用户返回任何内容。那么如何验证这条路由(以便它传递用户数据),同时即使用户未通过身份验证也允许路由继续进行?

(我尝试在路由器页面上进行有条件的身份验证检查,但似乎用户已经通过身份验证,所以它始终保持错误。)

编辑:我还应该注意,我正在使用带有密码授予和访问令牌的 API 路由。

【问题讨论】:

  • 你可以复制并粘贴名称中间件 auth:api 的内容,你会在 karnal 中找到它
  • 这是 Laravel 5.3 的内置 Auth ('auth' => \Illuminate\Auth\Middleware\Authenticate::class,)

标签: laravel laravel-5


【解决方案1】:

从当前路由组(应用身份验证中间件)中删除此路由。

然后

public function __construct()
{
    if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) {
        $this->middleware('auth:api');
    }
}

然后

if (Auth::check()) {
    // Auth users
} else{ 
    //Guest users 
}

【讨论】:

  • 我刚刚使用了您的提示,它在 localhost 中运行良好。然后它在服务器中显示未经身份验证。有什么想法吗?
【解决方案2】:

我也遇到了同样的情况。

由于 auth 中间件只检查经过身份验证的用户,我们可以为未经过身份验证的用户使用客户端凭据。

客户端凭据有一个单独的中间件,位于 Laravel\Passport\Http\Middleware\CheckClientCredentails。

我创建了一个自定义中间件来组合这两个中间件以允许其中一个通过。

这是我的自定义中间件

namespace Laravel\Passport\Http\Middleware;

use Closure;
use League\OAuth2\Server\ResourceServer;
use Illuminate\Auth\AuthenticationException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;

class CheckClientCredentials
{
    /**
     * The Resource Server instance.
     *
     * @var ResourceServer
     */
    private $server;

    /**
     * Create a new middleware instance.
     *
     * @param  ResourceServer  $server
     * @return void
     */
    public function __construct(ResourceServer $server)
    {
        $this->server = $server;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     *
     * @throws \Illuminate\Auth\AuthenticationException
     */
    public function handle($request, Closure $next, ...$scopes)
    {
        $psr = (new DiactorosFactory)->createRequest($request);

        try{
            $psr = $this->server->validateAuthenticatedRequest($psr);
        } catch (OAuthServerException $e) {
            throw new AuthenticationException;
        }

        foreach ($scopes as $scope) {
           if (!in_array($scope,$psr->getAttribute('oauth_scopes'))) {
             throw new AuthenticationException;
           }
         }

        return $next($request);
    }
}

内核.php

protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.api' => \App\Http\Middleware\APIAuthenticate::class,
    ....

路由\api.php

Route::group([
    'namespace' => 'API',
    'middleware' => 'auth.api:api',
], function(){
    ....

【讨论】:

  • 您的自定义中间件“APIAuthrnticate”在哪里?
  • 使用此中间件时,我无法从请求中的用户提供程序中检索用户实例(request()->user() 返回 null),因此未设置对护照返回的 JWT 令牌的授权正确,特别是oauth_user_id
【解决方案3】:

从未经身份验证(未分配 auth:api 中间件)路由的处理程序方法中,尝试:

Auth::guard("api")->user();

如果已填充,则您的未受保护的路由可以将访问视为经过身份验证。如果不是,它是一个随机用户访问该路由,可以这样对待。

【讨论】:

    【解决方案4】:

    不要将您希望允许来宾用户和经过身份验证的用户的那些 URL 放在 auth 中间件中。因为 auth 中间件只允许经过身份验证的用户。

    要检查经过身份验证和未经身份验证的用户,您可以在视图中使用以下代码

     @if (Auth::guest())
          //For guest users
     @else
          //for authenticated users
     @endif
    

    已编辑:在控制器中使用

    if (Auth::check()) {
        // Auth users
    } else{ 
      //Guest users 
    }
    

    【讨论】:

    • 在您编写 html 代码的视图刀片文件中。
    • 我没有使用视图 - 我在 Laravel 5.3 中使用 API 路由。我更新了我的问题以添加此信息。
    • 当我这样做时(我的路由不使用中间件),并且我在控制器方法中运行Auth::user()Auth::check(),即使请求已通过身份验证,我也总是分别得到 null 和 false。
    【解决方案5】:

    @Yves 的回答几乎是正确的。但是一个小小的改变,

    我们需要检查键值是否不为空,而不是array_key_exists。因为它始终具有该键但为空值。所以,而不是控制器构造检查这样的授权标头。

    if ($_SERVER['HTTP_AUTHORIZATION']) {
        $this->middleware('auth:sanctum');
    }
    

    然后您可以像这样检查经过身份验证的用户:

    if (auth()->check()) {
        // User is logged in and you can access using
        // auth()->user()
    } else {
        // Unauthenticated
    }
    

    【讨论】:

      【解决方案6】:

      供圣所使用:

          if (Auth::guard('sanctum')->check()) {
              // user is logged in
              /** @var User $user */ $user = Auth::guard('sanctum')->user();
          } else {
              // user is not logged in (no auth or invalid token)
          }
      

      【讨论】:

        【解决方案7】:

        你可以使用这个例子:

        @if(Auth::user())
           echo "authincatesd user";
        @else
           echo "unauthorised";
         @endif
        

        【讨论】:

        • 即使我已通过身份验证,我也会为 Auth::user() 返回 null
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-11
        • 2019-03-12
        • 2017-01-06
        • 1970-01-01
        • 2019-09-25
        • 1970-01-01
        相关资源
        最近更新 更多