且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Laravel 5.6-自耗API的Passport JWT httponly cookie SPA身份验证?

更新时间:2022-06-25 09:43:25

Laravel Passport JWT

Laravel Passport JWT

  1. 要使用此功能,您需要禁用cookie序列化. Laravel 5.5在cookie值的序列化/反序列化方面存在问题. 您可以在此处了解更多信息( https://laravel.com/docs/5.5/upgrade)

  1. To use this feature you need to disable cookie serialization. Laravel 5.5 has an issue with serialization / unserialization of cookie values. You can read more about this here (https://laravel.com/docs/5.5/upgrade)

请确保

  • 您的刀片模板头中有<meta name="csrf-token" content="{{ csrf_token() }}">

axios设置为对每个请求使用csrf_token.

axios is set to use csrf_token on each request.

您应该在resources/assets/js/bootstrap.js

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
  window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
  console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

  1. 此处说明设置身份验证路由( https://laravel.com/docs/5.5/authentication)
  2. 此处说明设置护照( https://laravel.com/docs/5.5/passport).
  1. Setup auth routes explained here (https://laravel.com/docs/5.5/authentication)
  2. Setup passport explained here (https://laravel.com/docs/5.5/passport).

重要的部分是:

  • Laravel\Passport\HasApiTokens特征添加到您的User模型
  • config/auth.php
  • 中将api身份验证保护的driver选项设置为passport
  • \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,中间件添加到app/Http/Kernel.php
  • 中的web中间件组中
  • add the Laravel\Passport\HasApiTokens trait to your User model
  • set the driver option of the api authentication guard to passport in your config/auth.php
  • add the \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class, middleware to your web middleware group in app/Http/Kernel.php

请注意,您可能可以跳过迁移并创建客户端.

Note you probably can skip migrations and creating clients.

  1. /login发出POST请求,以传递您的凭据.您可以提出AJAX请求或普通表单提交.
  1. Make a POST request to /login passing your credentials. You can make an AJAX request or normal form submit.

如果登录请求是AJAX(使用axios),则响应数据将是HTML,但是您感兴趣的是状态码.

If the login request is AJAX (using axios) the response data will be the HTML but what are you interested at is the status code.

axios.get(
  '/login, 
  {
    email: 'user@email.com',
    password: 'secret',
  },
  {
    headers: {
      'Accept': 'application/json', // set this header to get json validation errors.
    },
  },
).then(response => {
  if (response.status === 200) {
      // the cookie was set in browser
      // the response.data will be HTML string but I don't think you are interested in that
    }
    // do something in this case
}).catch(error => {
  if (error.response.status === 422) {
    // error.response.data is an object containing validation errors
  }
  // do something in this case
});

登录时,服务器通过提供的凭据查找用户,并根据用户信息(ID,电子邮件...)生成令牌(此令牌未保存在任何地方) 然后服务器返回带有包含生成的令牌的加密cookie的响应.

On login, the server finds the user by credentials provided, generates a token based on user info (id, email ...) (this token is not saved anywhere) then the server returns a response with an encrypted cookie that contains the generated token.

  1. 对受保护的路由进行API调用.

假设您的路由受保护

Route::get('protected', 'SomeController@protected')->middleware('auth:api');

您可以像往常一样使用axios进行ajax调用. Cookie会自动设置.

You can make an ajax call using axios as normal. The cookies are automatically set.

axios.get('/api/protected')
  .then(response => {
    // do something with the response
  }).catch(error => {
    // do something with this case of error
  });

当服务器收到呼叫时,解密请求laravel_cookie并获取用户信息(例如:id,email ...) 然后使用该用户信息进行数据库查找,以检查该用户是否存在. 如果找到用户,则授权该用户访问所请求的资源. 否则返回401.

When the server receives the call decrypts the request laravel_cookie and get user information (ex: id, email ...) Then with that user info does a database lookup to check if the user exists. If the user is found then the user is authorized to access the requested resource. Else a 401 is returned.

使JWT令牌无效.正如您提到的评论,无需担心这一点,因为此令牌未保存在服务器上的任何位置.

Invalidating the JWT token. As you mention the comment there's no need to worry about this since this token is not saved anywhere on the server.

关于第3点,Laravel 5.6 Auth具有新的方法logoutOtherDevices.您可以从此处了解更多信息( https://laracasts .com/series/whats-new-in-laravel-5-6/episodes/7 ) 因为文档非常简短.

Regarding point 3 Laravel 5.6 Auth has a new method logoutOtherDevices. You can learn more from here (https://laracasts.com/series/whats-new-in-laravel-5-6/episodes/7) since the documentation is very light.

如果您无法更新Laravel版本,则可以查看5.6中的操作,并为5.5构建自己的实现.

If you can't update your Laravel version you can check it out how is done in 5.6 and build your own implementation for 5.5

问题第4点.看一下app/Http/Controllers/Auth中找到的控制器.

Point 4 from your question. Take a look at controllers found in app/Http/Controllers/Auth.

关于access_tokens和refresh_tokens,这是一种完全不同且更复杂的方法. 您可以在网上找到许多说明方法的教程.

Regarding access_tokens and refresh_tokens this is a totally different and more complex approach. You can find lots of tutorials online explaining how to do it.

希望对您有帮助.

PS.祝新年快乐!! :)

PS. Have a Happy New Year!! :)