在Laravel 5.3中与未经身份验证和经过身份验证的用户共享相同的路由

时间:2016-09-20 11:57:24

标签: laravel laravel-5

我有一条路线,我在那里使用auth中间件并且效果很好。

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

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

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

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

7 个答案:

答案 0 :(得分:3)

我遇到了同样的情况。

由于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);
    }
}

Kernal.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(){
    ....

答案 1 :(得分:2)

从当前路由组(应用auth中间件)中删除此路由。

然后

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

然后

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

答案 2 :(得分:1)

请不要在auth中间件中为访客用户和经过身份验证的用户提供这些网址。因为auth中间件仅允许经过身份验证的用户。

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

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

已编辑:在控制器中使用

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

答案 3 :(得分:1)

您可以使用此示例:

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

答案 4 :(得分:1)

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

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

如果已填充,则您不受保护的路由可以将访问视为已认证。如果不是,则表示该用户是随机访问该路线的用户,可以这样对待。

答案 5 :(得分:0)

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

我们需要检查key值是否不为空,而不是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 :(得分:0)

供圣所使用:

    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)
    }