Sanctum Laravel 8 用于 API 身份验证的问题(不会在注销时删除令牌)

Posted

技术标签:

【中文标题】Sanctum Laravel 8 用于 API 身份验证的问题(不会在注销时删除令牌)【英文标题】:Problems with Sanctum Laravel 8 for API Authenthication (won't delete token on logout) 【发布时间】:2021-06-12 16:42:27 【问题描述】:

我们为 API 身份验证正确安装了 Sanctum。 登录后,我们区分了两个角色:一个是管理员,另一个是在 laratrus 的帮助下的用户。 我们还创建了一个新的控制器来处理所有身份验证部分(注册、登录、注销)。 登录后,我们区分了两个角色:一个是管理员,另一个是在 laratrust 库的帮助下的用户。 问题是当我们尝试使用邮递员登录时,它给了我们这个错误:

即使应用程序在数据库中正确插入了令牌行。第二个问题是当我们尝试使用浏览器登录时,它没有给我们任何错误并且重定向是正确的,但是当我们尝试注销令牌时仍然存在于数据库中。

这是我们的 AuthController.php

protected function register(Request $request)
    
    


protected function login(Request $request)

    $validator = Validator::make($request->all(),[
        'email' => 'required|email',
        'password' => 'required'
    ]);

    if($validator->fails())
        return response()->json([
            'status_code' => '400',
            'message' => 'Bad request'
        ]);
    

    $credentials = request(['email', 'password']);

    if(!Auth::attempt($credentials))

        return response()->json([
            'status_code' => '500',
            'message' => 'Non autorizzato'
        ]);
    

    $user = User::where('email', $request->email)->first();

    $token = $user->createToken('authToken')->plainTextToken;

    if($user->hasRole('administrator'))
        
        return redirect()
            ->route('admin')
            ->with([
                'status_code' => '200',
                'token' => $token
            ]);
    
    if($user->hasRole('user'))
        
        return redirect()
            ->route('cliente')
            ->with([
                'status_code' => '200',
                'token' => $token
            ]);
    



protected function logout(Request $request)

    $request->user()->currentAccessToken()->delete();

    return redirect()
            ->route('welcome')
            ->with([
                'status_code' => '200',
                'message' => 'token cancellato correttamete'
            ]);

这是我们的api.php:

Route::post('/login', [App\Http\Controllers\Auth\AuthController::class, 'login'])->name('api.login');

Route::group(['middleware' => ['auth:sanctum']], function () 

//Operazioni di gestione e creazione corso scii per maestri
Route::post('/tipo', [App\Http\Controllers\ApiController::class, 'createtipo']);
Route::post('/corso', [App\Http\Controllers\ApiController::class, 'createcorso']);
Route::get('/mostracorsi', [App\Http\Controllers\ApiController::class, 'mostracorsi']);
Route::get('/mostracorso/idCorso', [App\Http\Controllers\ApiController::class, 'mostracorso']);
Route::put('/updatecorso/idCorso', [App\Http\Controllers\ApiController::class, 'updatecorso']);
Route::delete('/deletecorso/idCorso', [App\Http\Controllers\ApiController::class, 'deletecorso']);

//Operazioni di gestione prenotazioni ed iscrizioni per clienti impianto scii
Route::post('/iscrizione', [App\Http\Controllers\ApiController::class, 'iscrizione']);
Route::get('/vedicorso/idCorso', [App\Http\Controllers\ApiController::class, 'vedicorso']);
Route::delete('/deleteiscrizione/idUtente', [App\Http\Controllers\ApiController::class, 'deleteiscrizione']);

//Route per il logout
Route::post('/logout', [App\Http\Controllers\Auth\AuthController::class, 'logout'])->name('api.logout');
);

另外,我们如何使用 Laravel 模板刀片附加 API 系统身份验证?

【问题讨论】:

【参考方案1】:

您的问题可能是您没有在前端保存令牌,看起来您成功登录但您没有保存令牌。 Sanctum 中间件仅在从前端识别标头后才允许请求我不确定您的前端是什么,但我相信所有 SPA 的工作方式都相同,我确信问题出在前端而不是后端。参考我的 vue js SPA。我在登录时保存令牌,之后每当我发出请求时,我都会通过 axios.defaults.headers.common['Authorization'] = Bearer $this.token 访问令牌。您可以在下面看到我的示例是成功登录后的仪表板

  <script>
export default 
  components:  SideMenu, Profile, Sidebar, PersonalDetails ,
  data()
      return 
          drawer: true,
          currentUser: ,
          user: ,
          user_info:  profile:  ,
          token: localStorage.getItem('user_data')
      
  ,
 methods: 
      getUser()
        axios.get('http://127.0.0.1:8000/api/user').then(response => 
            this.currentUser = response.data
            this.user = this.currentUser.user
            if (this.user.roles= []) 
                this.$router.push( name: 'Roles')
            
            axios.get('http://127.0.0.1:8000/api/profile/' + this.user.id).then(response => 
                this.user_info = response.data
                console.log(response.data)
            )
        ).catch(errors => 
            console.log(errors)
        )
      ,
  ,
  created()
      axios.defaults.headers.common['Authorization'] = `Bearer $this.token` 
      this.getUser()  
      this.isCreated = true   
  

</script>

我相信您的注销功能会在您解决此问题后正常工作。

【讨论】:

我们在 Laravel Blade 模板上使用了 jQuery,效果一样吗? 根据 laravel sactum 文档,我认为这不是一个好主意,它用于 API,这意味着它是来自不同 url 的数据交换,但 jQuery 会从同一个网站发出请求。我建议你们使用默认的 laravel 身份验证方法。 jQuery 对此没有任何问题,因为它共享默认会话的同一站点

以上是关于Sanctum Laravel 8 用于 API 身份验证的问题(不会在注销时删除令牌)的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Sanctum Token API 身份验证在 Postman 中不起作用

Laravel Sanctum 令牌()未定义

如何在没有 SPA 或图形界面的情况下,仅通过 POSTMAN 访问 Laravel Sanctum 的 API 路由?

Laravel Sanctum auth:sanctum 路由允许在没有承载令牌的情况下访问

带有 Sanctum 身份验证的 Laravel 8 (Reactjs SPA)

如何使用 CSRF 令牌测试 Laravel / Sanctum 端点