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

9

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

我正在使用Postman运行一些测试,它正常工作。当我尝试访问没有有效令牌的路由时,我看到响应是我的应用程序(登录页面的)HTML。我该如何返回未经授权消息而不是完整的登录页面?我需要创建自定义中间件吗?

控制器

class ExampleController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api');
    }

    public function show(Request $request) {
        return response()->json($request->user()->name);
    }
 }
5个回答

12
如果您使用的是 Laravel 5.6 或更低版本,请在 app/Exceptions/Handler.php 类中添加以下方法:
/**
 * 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'));
}

并且在上述提到的同一文件中的类之前添加以下行:
use Illuminate\Auth\AuthenticationException;

请在Postman的Headers部分中添加以下头信息:
X-Requested-With:XMLHttpRequest

该方法已经存在,我错过了请求头X-Requested-With:XMLHttpRequest,谢谢! - user3253002
2
这个处理程序是针对未经身份验证的情况,但问题实际上是关于未经授权的。 - realtebo

10
对于使用Laravel 6或更高版本(Laravel 8Laravel 10)的用户, 请在app/Http/Middleware/Authenticate中添加一个"unauthenticated"函数,如下所示:
<?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));
    }
}

非常感谢,这个有文档记录吗? 编辑:找到了 --> https://laravel.com/docs/5.6/authentication - Ben jamin
这是一个旧链接,与此线程上的其他答案相匹配。在 Laravel > 6 中有所不同:https://laravel.com/docs/10.x/authentication - undefined

4

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

Content-Type: application/json

1

确保您发送了正确的头部信息

Accept        application/json

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

1

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”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接