注销不适用于 Laravel JWT-auth

Posted

技术标签:

【中文标题】注销不适用于 Laravel JWT-auth【英文标题】:Logout doesn't work with Laravel JWT-auth 【发布时间】:2019-07-16 12:43:11 【问题描述】:

我使用 JWT-auth 和 Laravel 框架来验证用户。 Laravel 用作服务端框架,前端代码在我们自己开发的框架中。所以我们使用api而不是web来实现认证。登录在此环境中运行良好,而注销和刷新令牌无法按我的意愿执行。我按照JWT-auth documentation 所说的那样配置所有内容。

路由.php

Route::group(['middleware' => 'api', 'prefix' => 'user', 'namespace' => 'User'], function () 
   Route::post('/login', 'AuthController@login'); // login
   Route::post('/logout', 'AuthController@logout'); // logout (invalidate token)
   Route::post('/refresh', 'AuthController@refresh'); // refresh token);

kernel.php

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'password',
        'model' => App\User::class,
    ],

    /*'users' => [
        'driver' => 'database',
        'table' => 'user',
    ],*/
],

用户\AuthController

<?php

namespace App\Http\Controllers\User;

use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use AjaxResponse;
use Log;

class AuthController extends Controller

    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    
        $this->middleware('auth:api', ['except' => ['login']]);
    

    /**
     * login
     * @param Request $request 
     * @return mixed
     */
    public function login(Request $request)
    
        $credentials = $request->only('phone', 'password');

        if (! $token = auth()->attempt($credentials)) 
            return AjaxResponse::fail(4001);
        

        return $this->respondWithToken($token);
    

    /**
     * logout(invalidate token)
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    
        Log::debug('yyyyyyyyy');
        auth()->logout();

        return AjaxResponse::succeed(['message' => 'Successfully logged out']);
    

    /**
     * refresh token
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    
        return $this->respondWithToken(auth()->refresh());
    

    /**
     * get token structure
     * @param $token
     * @return mixed
     */
    protected function respondWithToken($token)
    
        if (Auth::user()['deleted_at'] || ! Auth::user()['is_active'])
            return AjaxResponse::fail(4001);
        else
            return AjaxResponse::succeed([
                'access_token' => $token,
                'token_type' => 'bearer',
                'expires_in' => auth()->factory()->getTTL() * 60,
                'user_name' => Auth::user()['name'],
                'user_admin' => (bool)Auth::user()['is_admin']
            ]);
    

'yyyyyyyyy' 无法记录。所以看起来AuthController中的logout函数没有被调用。

我写错了什么或遗漏了什么吗?提前致谢。

【问题讨论】:

消息日志yyyyyyyyy 工作正常吗?消息'Successfully logged out' 回来了吗?或者简单地说,没有失效的令牌? @cbaconnier 我刚刚更新了我的问题。请重新检查。 你的截图是你的POST当你点击/logout时的结果,对吗?在这种情况下,您所做的请求可能是错误的。由于您使用的是 API,它应该是 Content-Type: application/json 并且标头应该包含 Authorization: Bearer &lt;token&gt; 除了我解释的内容之外:您所做的请求可能是错误的。我猜这是因为我看到的是 html 屏幕截图。 Laravel 通常会将您重定向到/login(不是/api/login,因为它不会将请求视为json 并且不会看到您已通过身份验证。 @cbaconnier 我已经找到了让它工作的方法,但是我没有清楚地解释逻辑。 【参考方案1】:

经过几次尝试,我已经更改了 AuthController 的构造函数,并且成功了。

用户\AuthController

public function __construct()

    $this->middleware('auth:api', ['except' => ['login', 'refresh', 'logout']]);

我已将函数添加为 'except' 的值,我希望在其中使当前会话无效。

【讨论】:

以上是关于注销不适用于 Laravel JWT-auth的主要内容,如果未能解决你的问题,请参考以下文章

Keycloak 注销不适用于公开 REST 服务的“仅承载”应用程序

JAAS 注销不适用于自定义登录模块

从选项卡注销,不适用于所有其他选项卡

重定向适用于登录但不适用于注销

注销功能不适用于 ASP.NET 标识

注销功能不适用于 ASP.NET 标识