laravel - 如果不用于令牌,Sanctum 和 Laravel 的默认身份验证是否相同?
问题描述
我不太确定 Laravel 文档中的含义,所以我要求确定。
我们一方面有 Laravel 的默认身份验证,另一方面有 Sanctum 的默认身份验证。
据说 Sanctum 可以做 Tokens 或者简单地实现 auth。:
对于此功能,Sanctum 不使用任何类型的代币。相反,Sanctum 使用 Laravel 内置的基于 cookie 的会话身份验证服务。这提供了 CSRF 保护、会话身份验证以及防止身份验证凭据通过 XSS 泄漏的好处。只有当传入请求来自您自己的 SPA 前端 (Vue.js) 时,Sanctum 才会尝试使用 cookie 进行身份验证。
因此,如果从不使用令牌,Sanctum 与默认的身份验证方法基本相同,我说的对吗?基本上,它是否实现了默认身份验证并在需要时添加令牌?如果是这样,那么 sanctum 和 passport 有什么区别,因为它们做同样的事情,但据说 Sanctum 是轻量级的。这实际上是什么意思?
谢谢阅读
解决方案
因此,如果从不使用 Token,Sanctum 与默认的 Authentication 方法基本相同,我说的对吗?
是的,它使用 laravel 的默认身份验证。
看看 sanctum 守卫(下面的代码取自 github。它最后一次提交是在 4 月 11 日,sanctum 2.x)
<?php
namespace Laravel\Sanctum;
use Illuminate\Contracts\Auth\Factory as AuthFactory;
use Illuminate\Http\Request;
class Guard
{
/**
* The authentication factory implementation.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* The number of minutes tokens should be allowed to remain valid.
*
* @var int
*/
protected $expiration;
/**
* Create a new guard instance.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @param int $expiration
* @return void
*/
public function __construct(AuthFactory $auth, $expiration = null)
{
$this->auth = $auth;
$this->expiration = $expiration;
}
/**
* Retrieve the authenticated user for the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function __invoke(Request $request)
{
if ($user = $this->auth->guard(config('sanctum.guard', 'web'))->user()) {
return $this->supportsTokens($user)
? $user->withAccessToken(new TransientToken)
: $user;
}
if ($token = $request->bearerToken()) {
$model = Sanctum::$personalAccessTokenModel;
$accessToken = $model::findToken($token);
if (! $accessToken ||
($this->expiration &&
$accessToken->created_at->lte(now()->subMinutes($this->expiration)))) {
return;
}
return $this->supportsTokens($accessToken->tokenable) ? $accessToken->tokenable->withAccessToken(
tap($accessToken->forceFill(['last_used_at' => now()]))->save()
) : null;
}
}
/**
* Determine if the tokenable model supports API tokens.
*
* @param mixed $tokenable
* @return bool
*/
protected function supportsTokens($tokenable = null)
{
return $tokenable && in_array(HasApiTokens::class, class_uses_recursive(
get_class($tokenable)
));
}
}
如果你检查_invoke()
方法,
if ($user = $this->auth->guard(config('sanctum.guard', 'web'))->user()) {
return $this->supportsTokens($user)
? $user->withAccessToken(new TransientToken)
: $user;
}
经过身份验证的用户是使用
$user = $this->auth->guard(config('sanctum.guard', 'web'))->user()
在检查了 sanctum 配置文件后,目前没有sanctum.guard
配置(可能是为了将来的某个版本),所以 sanctumweb
默认检查守卫,所以它基本上和你的默认 web 路由做同样的事情。
但是你误解了圣所的用途。Sanctum 用于 API 身份验证,而不用于 Web 身份验证(尽管它也可以用于 Web 身份验证)。Sanctum 的非令牌身份验证使您的 SPA 能够使用与移动应用程序(使用令牌身份验证)相同的 API,而无需令牌并提供 csrf 和基于会话的身份验证的好处。
为了帮助您更好地理解,假设您已经构建了一个使用令牌的 API(如果它已经使用 sanctum 作为令牌,这会使事情变得更简单)进行身份验证。现在您希望构建一个使用相同 API 的 SPA(可以在 laravel 项目本身内部构建,也可以是在同一域或不同域上构建的单独项目),但由于这将由您构建,因此它是一个受信任的站点,因此您不希望它使用令牌,而是使用 laravel 的默认基于会话的身份验证以及 csrf 保护,同时还使用相同的 api 路由。SPA 将通过 ajax 与服务器通信。您还希望确保仅允许您的 SPA 使用基于会话的身份验证,而不允许其他第三方站点使用它。
所以这就是 Sanctum 的用武之地。您只需要将 Sanctum 中间件添加到您的api
路由组app/Http/Kernel.php
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
然后配置 sanctum 以允许您的 SPA 域并配置 cors(查看文档以了解如何执行此操作)。然后只需将auth:sanctum
中间件添加到您的路由中,您就完成了服务器端设置。
现在,如果请求具有令牌或有状态(会话 cookie),这些路由将对用户进行身份验证。
现在您的 SPA 可以在没有令牌的情况下与您的 API 进行通信。
要获得csrf保护,csrf-cookie
先调用请求,这会在你的cookies中设置一个csrf token,axios会自动附加到后续请求中
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
})
圣所和护照有什么区别,因为它们做同样的事情,但据说圣所是轻量级的。
好吧,就像它说的那样,圣所是轻量级的。这是因为 Passport 提供了完整的 Oauth 功能,而 Sanctum 只专注于创建和管理令牌。为了简单地解释 Oauth,您必须在不同的站点上看到过这些Sign in with Google
, Sign in with Facebook
, Sign in with Github
,然后您可以使用您的 google/facebook/github 帐户将其签名到这些站点。这是可能的,因为 Google、Facebook 和 Github 提供了 Oauth 功能(只是一个简单的例子,不做太多细节)。对于大多数网站,您并不需要 Passport,因为它提供了许多您不需要的功能。对于简单的 api 身份验证,Sanctum 绰绰有余
推荐阅读
- excel - VBA:如果然后在之后有2个语句
- http-redirect - 重定向到这样的网址是否安全:“https://example.com/”+ userData?
- html - 边框没有回来,从 EDGE 中的元素中删除了悬停
- javascript - 用于 Firefox 的带有 unicode 符号的复选框
- node.js - Travis 部署阶段未在条件下运行,如果:分支 = 主和标签存在并且类型 = 推送
- python - 在python中删除带有条件的行
- amazon-web-services - AWS Lambda 访问 API Gateway
- amazon-kinesis - Kinesis 消耗滞后监控
- wso2 - 消息存储支持回滚?
- python - Keras 中的权重共享