如何使用 Laravel API 身份验证返回未授权

Posted

技术标签:

【中文标题】如何使用 Laravel API 身份验证返回未授权【英文标题】:How to return unauthorized using Laravel API Authentication 【发布时间】:2019-09-20 07:33:33 【问题描述】:

我正在使用带有令牌的 Laravel API 身份验证。 (如此处所述: https://laravel.com/docs/5.8/api-authentication#protecting-routes)

我正在使用 Postman 进行一些测试,它运行良好。当我尝试在没有有效令牌的情况下访问路由时,我看到响应是我的应用程序的(html 的)登录页面。如何返回Unauthorized 消息而不是完整的登录页面?我必须创建自定义中间件吗?

控制器

class ExampleController extends Controller

    public function __construct()
    
        $this->middleware('auth:api');
    

    public function show(Request $request) 
        return response()->json($request->user()->name);
    
 

【问题讨论】:

【参考方案1】:

请在文件位置app/Exceptions/Handler.php中添加类Handler中的方法

/**
 * Convert an authentication exception into an unauthenticated response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Auth\AuthenticationException  $exception
 * @return \Illuminate\Http\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)

    if ($request->expectsJson()) 
        return response()->json(['error' => 'Unauthenticated.'], 401);
    

    return redirect()->guest(route('login'));

并且还在上面提到的同一文件中的类上方添加以下行: 使用 Illuminate\Auth\AuthenticationException;

在标题部分的邮递员中,请添加以下标题: X-Requested-With:XMLHttpRequest

希望这有助于解决问题。谢谢。

【讨论】:

方法已经有了,我错过了标题X-Requested-With:XMLHttpRequest谢谢! 这个句柄未经身份验证,但问题是关于未经授权的【参考方案2】:

确保在您的请求中发送正确的标头

Content-Type: application/json

【讨论】:

【参考方案3】:

Laravel 8 更新:

默认处理程序已经处理这种情况

文件:\Illuminate\Foundation\Exceptions\Handler.php

/**
 * Convert an authentication exception into a response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Auth\AuthenticationException  $exception
 * @return \Symfony\Component\HttpFoundation\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)

    return $request->expectsJson()
                ? response()->json(['message' => $exception->getMessage()], 401)
                : redirect()->guest($exception->redirectTo() ?? route('login'));

这就是 Laravel 在 \Illuminate\Http\Concerns\InteractsWithContentTypes.php 中处理 expectsJson 的方式

/**
 * Determine if the current request probably expects a JSON response.
 *
 * @return bool
 */
public function expectsJson()

    return ($this->ajax() && ! $this->pjax() && $this->acceptsAnyContentType()) || $this->wantsJson();



/**
 * Determine if the current request is asking for JSON.
 *
 * @return bool
 */
public function wantsJson()

    $acceptable = $this->getAcceptableContentTypes();

    return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);

所以请注意,请求的内容类型标头是无用的。有用的标头是“Accept: application/json”

【讨论】:

【参考方案4】:

确保您发送正确的标头

Accept        application/json

此外,您可以为此创建自己的中间件。

【讨论】:

【参考方案5】:

我正在使用带有护照的 Laravel 8。 就我而言,我必须在 app/Http/Middleware/Authenticate 中添加一个“未经身份验证”的函数,如下所示:

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

class Authenticate extends Middleware

    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string|null
     */
    protected function redirectTo($request)
    
        if (! $request->expectsJson()) 
            return route('login');
        
    

    // Add new method 
    protected function unauthenticated($request, array $guards)
    
        abort(response()->json(
            [
                'api_status' => '401',
                'message' => 'UnAuthenticated',
            ], 401));
    

【讨论】:

以上是关于如何使用 Laravel API 身份验证返回未授权的主要内容,如果未能解决你的问题,请参考以下文章

jwt api 身份验证如何工作(使用 dingo-laravel)

Laravel - 通过外部 API 进行身份验证

在 Laravel 中使用无需身份验证的 api 路由

如何使用另一个 API 的用户群在 laravel 中设置身份验证?

如何在 laravel 中进行前端 api 身份验证

如何在 Laravel 中为 REST API 创建身份验证