如何在 laravel 5.3 中验证没有 auth:api 中间件的用户?

Posted

技术标签:

【中文标题】如何在 laravel 5.3 中验证没有 auth:api 中间件的用户?【英文标题】:How to authenticate user without auth:api middleware in laravel 5.3? 【发布时间】:2017-07-17 19:40:30 【问题描述】:

我有一个任何用户都可以访问的公共路由。 (/timeline)。 在此操作中,如果用户已通过身份验证,我必须向他展示他是否喜欢该帖子。 如果路由有auth:api 中间件,我可以使用$request->user() 获得经过身份验证的用户,但如果我不使用auth:api 中间件,即使用户发送正确的access_token,我也无法检查用户是否经过身份验证。 如何在没有中间件的情况下检查 access_token 是否正确并在控制器中验证用户身份?

【问题讨论】:

【参考方案1】:

如果您使用的是Sanctum 而不是 Passport:

$request->user('sanctum');

【讨论】:

【参考方案2】:

您可以将守卫传递给您的方法,以检查用户是否使用特定守卫登录。

$request->user('api');

编辑

我只是想扩展我原来的答案。

使用$request->user() 与使用\Auth::user() 完全相同。

当您检索经过身份验证的用户时,Laravel 将从您的配置文件 auth.defaults.guard(全新安装时为 web)中默认保护。

所以当你打电话给$request->user()时,它实际上是$request->user('web')

当你使用 auth:api 时,Laravel 将使用 api 作为默认值。

这就是为什么它在使用 auth:api 时有效,但在使用默认保护时无效。

要解决您的问题,如果您有 Illuminate\Http\Request 实例,您可以调用 $request->user('api'),或者使用 Auth 外观直接调用 \Auth::guard('api')->user()

【讨论】:

您也可以在没有请求对象的情况下使用 Auth::guard('api')->user() @Gkiokan,我认为他已经有了其他东西的请求对象,因为他已经在使用它了。不过你的观点还是不错的。 正确。考虑这样一个事实,当您没有 Request 对象时,您可以使用 Guard 访问 User 对象。以防万一您不想使用或为什么没有请求对象。 :) 能否提供完整的校验码以了解流程的工作原理,谢谢 @ReemAziz 你说的“整个校验码”是什么意思?【参考方案3】:

我没有时间去挖掘代码,但是你可以看看 auth:api 中间件。在那里,您将了解身份验证过程是如何工作的。如果您还没有找到任何东西,请告诉我,我今晚会调查并改进我的答案。

在文件Laravel\Passport\Http\Middleware\CheckClientCredentials 中你会发现:

<?php

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

当您深入挖掘时,您会看到请求在此处得到验证 League\OAuth2\Server\RecourceServer.php。我猜你会在那里找到答案

【讨论】:

【参考方案4】:

您正在使用auth:api,所以我假设您正在谈论 JSON 请求。访问令牌通常位于请求的标头中,因此您可以像这样检查它

public function timeline(Request $request) 
    if ( $request->has('access_token') || $request->header('access_token') ) 
        $user = Auth::guard('api')->user();
    

    ...

【讨论】:

这在您没有将 Request 实例注入您的方法时更有用。谢谢

以上是关于如何在 laravel 5.3 中验证没有 auth:api 中间件的用户?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3记住我身份验证问题

Laravel 5.3记住我身份验证问题

没有身份验证的 Laravel 5.3 RESTFul API

Laravel 身份验证在 laravel 5.3 中无法正常工作

如何使用 Laravel Passport (5.3) 记录身份验证尝试

任何想法如何使用 vue js 和 vue 路由器在 laravel 5.3 中进行基于会话的身份验证