Laravel Passport APi - 隐式授权
Posted
技术标签:
【中文标题】Laravel Passport APi - 隐式授权【英文标题】:Laravel Passport APi - Implicit grant 【发布时间】:2018-06-19 08:04:54 【问题描述】:我想通过 angularjs 构建一个水疗中心,并使用 laravel 作为水疗中心的 api。通过阅读 laravel 护照的文档,我发现我需要为此目的使用隐式授权。但我不确定它应该如何从前到后工作。我只想能够使用用户名和密码登录用户,然后使用它,我需要对该过程进行一些说明。这就是我想要的:
-
使用用户名和密码通过 html/javascript 通过 ajax 请求登录到 laravel (Angular)。
获取访问令牌以与 api 通信
在 spa 中执行一些操作,使用访问令牌触发对 api 的请求
从 api 获取数据以响应该请求。
但是我现在看到的隐式授权与我所期望的有点不同。
-
通过默认刀片登录表单登录 laravel(尚未使用 ajax 创建表单)
像这样重定向到 oauth/autorize
Route::get('/redirect', function ()
$query = http_build_query([
'client_id' => 'client-id',
'response_type' => 'token',
'scope' => '',
]);
return redirect('http://your-app.com/oauth/authorize?'.$query);
);
重定向显示批准或拒绝授权请求屏幕(这不是我所期望的)
当我批准请求时,浏览器会将我重定向到在 oAuth 客户端数据库条目中指定的重定向 uri,并带有访问令牌。我应该可以。更让我困惑的是,我似乎需要为每个 laravel 用户创建一个新客户端。我希望有 1 个代表我的水疗中心的 oauth 客户端可以访问 laravel 用户。你能澄清一下吗?
【问题讨论】:
- 我认为您应该使用密码授权类型,因为我们一直使用密码授权类型进行此类身份验证和授权。 但这会被认为是危险的,因为密码授予类型将返回一个刷新令牌,您需要将其安全地存储在客户端(浏览器)上。那是不可能的,对吧? 是的,你可以在客户端存储在cookies或storage中,你也可以返回自定义的东西。 不,你不能。因为如果您将其放入 cookie 或存储中,您计算机的其他用户可以根据需要检索刷新令牌并代表您采取行动。还有,如果我正确的话,另一个站点可能会读取您的 cookie 或本地存储并通过这种方式窃取您的刷新令牌所涉及的风险。简而言之:在客户端安全地存储刷新和访问令牌是不安全的。因此我认为,密码授予不是 SPA 的选项。 【参考方案1】:如果您要在 JavaScript 应用程序中使用密码授权,那么您必须使用服务器端代理进行身份验证并保护 client_secret 和刷新令牌。
代理管理整个 api 通信过程或仅管理身份验证部分并返回一个短暂的 access_token 。身份验证状态通过服务器会话进行管理。根据您的实现,必须保护某些请求免受 CSRF 攻击,因为大多数实现都使用 cookie。
否则,使用隐式授权对您的应用进行身份验证。 (有关详细信息,请参阅下面的链接)
https://auth0.com/docs/api-auth/tutorials/implicit-grant
https://oauth2.thephpleague.com/authorization-server/implicit-grant/
您可以使用此处所述的静默身份验证刷新您的访问令牌 https://auth0.com/docs/api-auth/tutorials/silent-authentication
注意:在大多数情况下,刷新令牌不会过期,这对于前端存储来说是一个很大的问题。
客户机密应始终保密。
编辑(2020 年)
现在是 2020 年,网络安全领域发生了很大变化。
存在隐式授权的已知漏洞,特别是因为您的 access_token 可以在飞行途中被拦截并重定向到另一台服务器。 现在建议使用 PKCE 流而不是隐式授权
Okta 有一篇关于 Is the OAuth 2.0 Implicit Flow Dead? 的非常好的文章和视频
Laravel 还发布了一个更简单的替代方案 Laravel Sanctum 我建议你看看它,因为它使用安全的仅 HTTP cookie 来存储访问令牌,并且还实现了开箱即用的 CSRF 保护
【讨论】:
我已经通过构建一个 php 代理解决了这个问题。它拦截所有请求并查看它试图到达的控制器。如果控制器属于某种接口类型,我会使用 guzzle 通过添加客户端 ID 和机密并添加授权令牌来执行请求。然后我将响应发送回 javascript 前端。我做和可能不做的是将授权和刷新令牌作为 cookie 存储在客户端浏览器中。但以加密形式。有更好的方法吗?会话 cookie 和我认为一样容易受到攻击,因为它指的是带有令牌的会话? 我的客户端密码和客户端 ID 存储在服务器端 b.t.w 对于任何寻找 laravel Airlock 的人来说,它现在被称为 Sanctum “由于关于名称 “Airlock” 的商标争议”。见这里:blog.laravel.com/airlock-renamed-to-sanctum以上是关于Laravel Passport APi - 隐式授权的主要内容,如果未能解决你的问题,请参考以下文章
laravel Passport - 创建 REST API 用户认证以及Dingo/Api v2.0+Passport实现api认证
php 使用Passport进行Laravel REST API身份验证:https://www.cloudways.com/blog/rest-api-laravel-passport-authen
每天一点点之laravel框架 - Laravel5.6 + Passport实现Api接口认证
Laravel 5.4建站06--API 认证系统 Passport