了解 Laravel Passport 中的授权类型
发表于 作者 Mohamed Said
OAuth2 是一种安全框架,它控制对应用程序受保护区域的访问,主要用于控制不同的客户端如何使用 API,确保它们拥有访问请求资源的适当权限。
Laravel Passport 是一个完整的 OAuth2 服务器实现;它旨在简化对基于 Laravel 的 Web 应用程序的 API 进行身份验证。
术语
在继续之前,我们需要了解以下定义
客户端 这是尝试使用我们的 API 的应用程序,在 Passport 中创建客户端是通过以下控制台命令完成的
php artisan passport:client
每个客户端都有一个密钥、名称、密钥、重定向 URI 和用户(应用程序创建者/所有者)。
资源所有者 这是拥有客户端尝试使用的数据的实体(用户)。
资源服务器 这就是我们的 API;它可能包含公共数据,不需要所有者权限即可读取,以及需要所有者权限的其他私有数据。
例如,公共端点可以是用于搜索推文的端点,它不需要特定资源所有者的权限。
另一方面,代表用户发布推文的端点是私有端点,与这些端点交互需要资源所有者的许可。
范围 它是访问特定数据或执行特定操作的权限。
您可以使用 Passport::tokensCan()
方法在您的 AuthServiceProvider
中定义范围。
Passport::tokensCan([ 'read-tweets' => 'Read all tweets', 'post-tweet' => 'Post new tweet',]);
授权 它是获取访问令牌的方法。
访问令牌 这是应用程序(客户端)与服务器(API)通信所需的令牌。
如何授权第三方应用程序
首先,我们需要使用以下命令创建一个测试应用程序
php artisan passport:client
Laravel Passport 会提示您询问用户 ID、应用程序名称和重定向 URI。
现在我们已经注册了客户端,我们可以使用“授权码授权”来获取访问令牌。
这种类型的授权通过将浏览器指向授权服务器来工作,用户可以在该服务器上登录到他们的帐户并授予应用程序访问权限,一旦授予访问权限,应用程序将发送另一个请求以获取访问令牌,使用此令牌,应用程序将能够进行进一步的请求。
在大多数情况下,您将使用这种授权类型来允许所有类型的应用程序使用您的基于 Laravel 的 API 私有端点,包括服务器端应用程序、JavaScript 应用程序和原生移动应用程序。
步骤 1:请求权限
在客户端应用程序中,您需要将用户指向以下 URL
http://resources.dev/oauth/authorize?client_id={CLIENT_ID}&redirect_uri={URI}&response_type=code&scope={SCOPE}
使用正确的 CLIENT_ID
和 URI
,如由 Passport 创建的客户端。
您可以将范围列为一个空格分隔的权限列表,您希望从资源所有者那里获得,例如
read-tweets post-tweets follow-others
现在,如果 Passport 已正确安装,以便路线发布在您的 AuthServiceProvider
中,如果一切正常,上述请求将显示一个漂亮的屏幕,要求用户授予应用程序权限,该屏幕将列出应用程序请求的所有范围。
如果用户拒绝访问,Passport 将将用户重定向到给定的 redirect_uri
,URL 中包含 error=access_denied
。
但是,如果用户批准了访问,Passport 将重定向到 redirect_uri
,URL 中包含 code={authorization_code_here}
。
步骤 2:获取访问令牌
现在我们有了授权代码,我们需要向 http://resources.dev/oauth/token
发送一个 POST
请求来获取访问令牌,请求的主体应包含以下内容
-
grant_type
:authorization_code
-
client_id
: 由 Passport 创建的 ID -
client_secret
-
redirect_uri
-
code
: 给定的授权代码
响应将是一个包含以下键的 JSON 对象
{ "token_type": "Bearer", "expires_in": 3155673600, "access_token": "eyJ0eXAiOiJKV1QiL....", "refresh_token": "XslU/K6lFZShiGxF1dPyC4ztIXBx9W1g..."}
刷新访问令牌
默认情况下,access_token
将不会在 100 年内过期,如果您不介意这一点,那么您不需要保存刷新令牌,否则,如果您希望 access_tokens
具有较短的生存期,您可以告诉 Passport
Passport::tokensExpireIn(Carbon::now()->addDays(15)); Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
如果您的令牌生存期很短,那么客户端需要保存 refresh_token
以便稍后使用它来颁发新的访问令牌。
要刷新访问令牌,客户端需要向 http://resources.dev/oauth/token
发送一个请求,请求参数如下
-
grant_type
:refresh_token
-
client_id
: 由 Passport 创建的 ID -
client_secret
-
refresh_token
-
scope
授权第一方应用程序
如果您正在授权自己信任的应用程序,则无需如此长的过程来获取访问令牌,您只需要要求用户提供用户名/电子邮件和密码即可让应用程序获取访问令牌。这种类型的授权称为 密码授权
。
您需要检查您的数据库以获取由 Passport 创建的密码客户端。
要为第一方应用程序获取访问令牌,您需要向 http://your-app.com/oauth/token
发送一个 POST
请求,请求参数如下
-
grant_type
:password
-
client_id
: -
client_secret
-
username
-
password
-
scope
响应将是一个包含以下键的 JSON 对象
{ "token_type": "Bearer", "expires_in": 3155673600, "access_token": "eyJ0eXAiOiJKV1QiL....", "refresh_token": "XslU/K6lFZShiGxF1dPyC4ztIXBx9W1g..."}
手动授权应用程序
Passport 提供了一种手动创建访问令牌的方法,这在多种情况下非常有用,例如开发过程中的测试,或者如果您允许用户通过他们的手机号码(而不是登录 Web 表单)在第三方应用程序上进行身份验证。
例如,第三方应用程序可能会显示一个电话号码字段供用户填写,填写完毕后,您服务器上的服务会向该号码发送一条包含访问代码的短信,用户将在收到短信后输入此代码,应用程序会与您服务器上的访问令牌进行交换。
要创建访问令牌
$token = $user->createToken('Pizza App', ['place-orders', 'list-orders'])->accessToken;