资讯专栏INFORMATION COLUMN

学习 Lumen 用户认证 (一)

wangzy2019 / 2630人阅读

摘要:在开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证和。附是为了在网络应用环境间传递声明而执行的一种基于的开放标准。

好久没写 PHP 代码了,尤其是 Lumen,我是 Lumen 的忠实用户,自从面世开始,我就将 Lumen 作为我 API 的主要框架使用。

但说到 API,不得不说的一个概念:「前后端分离」,现在越来越多的团队都采用前后端分离,彻底解放出前端的优势,也让后台更加集中于数据的输出。关于这方面的讨论,不在这里讨论了,可以参考一些文章深入研究:

https://segmentfault.com/a/11...

正因为有了前后端分离,后台关注于接口 API 的输出,当时 Lumen 的出现,就是为 RESTful API 而生的:

Decidedly Laravel. Delightfully Minimal.

Lightning fast micro-services and APIs delivered with the elegance you expect.

将 Lumen 作为接口框架使用,不得不解决一个核心问题:如何对访问者进行「认证」。

用户认证

Lumen 虽然与 Laravel 使用了相同的底层类库实现,但是因 Lumen 面向的是无状态 API 的开发,不支持 session,所以默认的配置不同。Lumen 必须使用无状态的机制来实现,如 API 令牌(Token)。

我们看看 Lumen 官网提供的例子:

use IlluminateHttpRequest;

$app->get("/post/{id}", ["middleware" => "auth", function (Request $request, $id) {
    $user = Auth::user();

    $user = $request->user();

    //
}]);

其中使用了中间件:"middleware" => "auth",我们看看 auth 中间件函数:

$app->routeMiddleware([
     "auth" => AppHttpMiddlewareAuthenticate::class,
 ]);

关联的是 Authenticate 类,我们看 Authenticate 的 handle 函数:

    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if ($this->auth->guard($guard)->guest()) {
            return response("Unauthorized.", 401);
        }

        return $next($request);
    }

首先会判断$this->auth->guard($guard)->guest()。我们继续跟进代码到 AuthManager 中:

/**
     * Attempt to get the guard from the local cache.
     *
     * @param  string  $name
     * @return IlluminateContractsAuthGuard|IlluminateContractsAuthStatefulGuard
     */
    public function guard($name = null)
    {
        $name = $name ?: $this->getDefaultDriver();

        return isset($this->guards[$name])
                    ? $this->guards[$name]
                    : $this->guards[$name] = $this->resolve($name);
    }

默认传入的 $name = null,所以我们看看 $this->getDefaultDriver()

/**
     * Get the default authentication driver name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app["config"]["auth.defaults.guard"];
    }

这就到了默认的配置 config 中了:

从 Lumen 源代码中可以看出 Lumen 的默认认证方式「api」。

我们再来看看 Laravel 的默认认证方式:

Laravel 默认采用「web」方式,而 web 方式是使用 session 来进行用户认证。这也就很好的说明了 Lumen 的无状态性。

接着我们需要明白 Lumen 如何通过「api」来进行用户认证的。

AuthServiceProvider 存放在 app/Providers 文件夹中,此文件中只有一个 Auth::viaRequest 调用。viaRequest 会在系统需要认证的时候被调用,此方法接受一个匿名函数传参,在此匿名函数内,你可以任意的解析 AppUser 并返回,或者在解析失败时返回 null,如:

/**
     * Boot the authentication services for the application.
     *
     * @return void
     */
    public function boot()
    {
        // Here you may define how you wish users to be authenticated for your Lumen
        // application. The callback which receives the incoming request instance
        // should return either a User instance or null. You"re free to obtain
        // the User instance via an API token or any other method necessary.

        $this->app["auth"]->viaRequest("api", function ($request) {
            if ($request->input("api_token")) {
                return User::where("api_token", $request->input("api_token"))->first();
            }
        });
    }

我们来看看 viaRequest 函数:

/**
     * Register a new callback based request guard.
     *
     * @param  string  $driver
     * @param  callable  $callback
     * @return $this
     */
    public function viaRequest($driver, callable $callback)
    {
        return $this->extend($driver, function () use ($callback) {
            $guard = new RequestGuard($callback, $this->app["request"], $this->createUserProvider());

            $this->app->refresh("request", $guard, "setRequest");

            return $guard;
        });
    }

这里关键的是 RequestGuard,这个类的核心函数:

/**
     * Get the currently authenticated user.
     *
     * @return IlluminateContractsAuthAuthenticatable|null
     */
    public function user()
    {
        // If we"ve already retrieved the user for the current request we can just
        // return it back immediately. We do not want to fetch the user data on
        // every call to this method because that would be tremendously slow.
        if (! is_null($this->user)) {
            return $this->user;
        }

        return $this->user = call_user_func(
            $this->callback, $this->request, $this->getProvider()
        );
    }

这个是判断是否获取用户信息,主要是调用callback 函数,而这个函数就是我们从 viaRequest 传入的:

function ($request) {
    if ($request->input("api_token")) {
                return User::where("api_token", $request->input("api_token"))->first();
            }
        }

而这只是举一个验证用户的例子,判断请求是否传入 api_token参数,并通过 User Model 直接匹配查找获取 User or null。

当然在实际开发中,我们不能只是简单的获取 api_token直接关联数据库查找用户信息。

在 API 开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证: JWT 和 OAuth2。

下一步

当前只是对 Lumen 的「用户认证」进行简单的了解,下一步通过对 「JWT」的学习,来看看如何利用 JWT 来有效的用户认证,更加安全的保障接口信息被有效的用户访问。

附:
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON 的开放标准 (RFC 7519)。该 token 被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该 token 也可直接被用于认证,也可被加密。

「未完待续」


coding01 期待您继续关注

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/25956.html

相关文章

  • 学习 Lumen 用户认证 (二) —— 使用 jwt-auth 插件

    摘要:在开发中,用户认证是核心,是数据是否有保障的前提,目前主要有两种常用方式进行用户认证和。为了学习在中的使用,最好的办法就是在程序员同志网搜索有关插件,找个最多的那个拿来研究研究。 通过上一篇《学习 Lumen 用户认证 (一)》https://mp.weixin.qq.com/s/KVUQE2DUetNB2kqxHs0VDg的学习,大致懂了 Lumen 的用户认证主要使用 「api」的...

    姘存按 评论0 收藏0
  • Lumen用户认证JWT,源码解读

    摘要:如何做用户认证根据文档描述,提供用户认证的接口,他的核心是看守器和提供器,看守器定义怎么认证用户,提供器定义怎么检索用户。 最近的一个PHP项目,上一个项目是采用ThinkPHP来弄的,因为很早就听说过Laravel的大名,所以进了Laravel的官网,意外发现了Lumen,正好我项目是提供API的,所以选择了Lumen,因为是Laravel的精简版,看了几天的Laravel文档,也总...

    AZmake 评论0 收藏0
  • Lumen 初体验(二)

    摘要:的现状目前是版本,是基于开发。入口文件启动文件和配置文件框架的入口文件是。在路由中指定控制器类必须写全命名空间,不然会提示找不到类。目前支持四种数据库系统以及。使用时发生错误,因为在文件中,的默认驱动是。 最近使用 Lumen 做了 2 个业余项目,特此记录和分享一下。 Lumen 的介绍 在使用一项新的技术时,了解其应用场景是首要的事情。 Lumen 的口号:为速度而生的 La...

    Cheriselalala 评论0 收藏0
  • Lumen中使用速度更快的PhpRedis扩展(更新队列驱动)

    摘要:发布,新增队列驱动,缓存驱动移动至,使用老版本的需要修改中缓存驱动加载位置。目前支持根据获取配置的基本读写等。和可以继续使用自带的驱动,两者互不影响。下一步如有需要可以继续完善这两部分的驱动。 欢迎关注我的博客 http://targetliu.com Lumen的确是一款适合做API,速度很快的框架。但是在项目中使用Redis时发现Lumen默认使用的 predis/predis 会...

    kyanag 评论0 收藏0
  • lumen5.5学习

    摘要:最近在学习框架写接口,记忆力比较差所以顺便写下笔记分割线因为直接学最新版的所以,记得开启的,,扩展还有可以用的打开命令 最近在学习lumen框架写API接口,记忆力比较差所以顺便写下笔记~ -----------------------------分割线-------------------------------- 因为直接学最新版的所以,PHP >=7.0记得开启php.ini的o...

    mindwind 评论0 收藏0

发表评论

0条评论

wangzy2019

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<