Home>Article>PHP Framework> Authorize Vue applications using Laravel Sanctum
Laravel Sanctum (formerly known as Laravel Airlock), released earlier this year, is a lightweight extension package that enables building on single page applications or native mobile applications The authentication process is made as simple and hassle-free as possible. Before this, you either used sessions-based web middleware or used externally integrated dependency packages, such as Tymon's jwt-auth. However, now, you can use Sanctum to complete stateful authentication and token-based authentication.
In this short test, I'll show you how to build a project from scratch using Laravel Sanctum. We will create a dummy API to authenticate a user through a Vue component and get the data associated with that logged in user.
If you want to skip the written tutorial, you can watch the video I made
You can also go directly to GitHub to view the full source code, which is located in [code] this repository.
Ready, let’s plate it together!
Creating a Test API
The first thing we need to do is create an API interface that we can get data from. I've conceived a super simple app that retrieves a list of secrets displayed for each user.
I have installed a Laravel application out of the box and configured it to run along with a MySQL database in a local environment that I set up using the Laravel Docker setup. The first thing I have to do is to create a model class and related migration files for our secret. Here we can easily use artisan to complete these operations through the command line.
php artisan make:model Secret --migration
Next, let’s open the migration file and add some data columns that are sufficient to describe a secret. I think what we need (besides the default ID and timestamp provided by Laravel) is a user_id integer field to associate with the user, and a field to actually hold the user secret information.
Schema::create('secrets', function (Blueprint $table) { $table->id(); $table->integer('user_id'); $table->text('secret'); $table->timestamps(); });
Then, run the database migration command to generate the users and secrets tables.
php artisan migrate
We need to make some simple modifications to the two model classes of the application to enable the association between the two model classes, so next let us open the two model class files, and Start modifying:
// User.php public function secrets() { return $this->hasMany('App\Secret'); } // Secret.php public function user() { return $this->belongsTo('App\User'); }
The last part of our API structure is the actual routes and controllers. We will only need to access a web page path to display all the secrets information related to the current user. So, I added the following to the routes/api.php file:
Route::get('/secrets', 'SecretController@index');
This controller can be easily created using the Artisan command:
php artisan make:controller SecretController
Open the controller we just created and let’s create index method, first returns all keys. Because right now we can't get authenticated users:
public function index() { return App\Secret::all(); }
Our dummy API is now complete, let's create some fake users and keys.
Polling the database
You can easily go directly into the database and populate the users manually, create controllers and forms for users to enter their own data, or use Artisan tinker to Semi-automatic user creation. I'll skip these methods and use the built-in Laravel factories to generate fake data for our users and keys.
Laravel comes with a UserFactory.php class out of the box for generating fake users. We will create a similar factory class for the key. Run the following Artisan command in the terminal:
php artisan make:factory SecretFactory --model=Secret
Open the generated file, we just populate each model with the two data user_id and secret:
$factory->define(Secret::class, function (Faker $faker) { return [ 'user_id' => 1, 'secret' => $faker->text ]; });
You may be wondering why we need Use hardcoding in user_id in the snippet above. Because I don't want to randomly generate it based on the number of users but want to have more control over it. Later, I'll show you how to override it when we start generating secrets.
Let’s start by creating a few fake users. Open the Tinker Shell by running the php artisan tinker command from the site root. Once open, we can create two users by running the global factory helper twice:
factory(App\User::class)->create(); // 与make不同,create 将我们的用户保存在数据库中
Now that we have them generated, let's create our secrets. I'm going to run the following in the tinker shell twice to create two for user_id 1:
Now that we have generated them, let's create our secrets. I ran the following command twice in tinker to create two keys for user_id 1:
factory(App\Secret::class)->create();
But what if the second key has a different ID for the user? Overriding any value in a factory class is easy, all we have to do is pass the override array to the create() method. Therefore, we will run the following command twice to create two keys for the second fake user: Bag.
Installation Laravel SanctumInstallation is a breeze and can be done by running a few commands in the terminal. First, let's install the package using Composer:
factory(App\Secret::class)->create(['user_id' => 2]);
Next run the following command to publish the migration file (and run the migration):
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate
Sanctum 安装的最后一部分要求我们修改 app\Http\Kernel.php 文件以包含一个中间件,该中间件会将 Laravel 的会话 cookie 注入到我们的应用程序前端中。这最终将使我们能够以经过身份验证的用户身份传递和检索数据:
'api' => [ EnsureFrontendRequestsAreStateful::class, 'throttle:60,1' ]
现在,我们可以进入应用程序的前端了!
构建前端
从 Laravel 7 开始,前端和身份验证模板已从主程序包中剥离,可以单独安装。为了进行演示,我们将使用它和 Vue 来构建前端。
在应用程序的根目录运行以下命令将帮助我们配置环境:
composer require laravel/ui php artisan ui vue --auth npm install && npm run dev
上面的命令做了三件事:
使用 Composer 安装 Laravel UI 软件包
生成 JS/UI 文件、身份验证模板和 package.json 修改
安装前端依赖项并编译开发环境的 JS/CSS 文件
我会把 welcome.blade.php 文件里的所有内容拷贝到 app.blade.php 文件里,然后把外部 div 里的内容删掉并添加一个 id="app" 属性。这将是我们 Vue 应用程序的挂载点,如刚才生成的 app.js 文件中所述。
让我们创建 Vue 组件,该组件将保存我们的登录表单并显示一些 secret.
创建 Vue 组件
在此之前,我们可以通过命令: php artisan ui vue 来生快速成我们的前端代码,它默认会生成一个 resources/js/components/ExampleComponent.vue 组件事例。好了,现在让我们创建新的组件:SecretComponent.vue,它的代码如下:
这里有两个字段返回,其中 secrets 字段是个数组,还有一个用户存储 email 和 password 字段的 formData 对象。
下面,我们将在 template 标签内构件我们的登录表单。
好了,一个登录表单创建完成,它可能看起来像下面这样:
在上面代码中,我们禁用了 form 表单的默认提交操作,并将它移交给 Vue 的 Submit 来处里。现在我们创建 handleLogin 方法来处理用户的登录请求:
最后,不要忘记将我们的组件注册到 resources/js/app.js 文件中:
Vue.component('secret-component', require('./components/SecretComponent.vue).default);
然后在 app.blade.php 中使用该组件。现在我们可以通过 handleLogin() 方法验证用户登录操作了。
用户验证
如果看过 Laravel Sanctum documentation 这篇文章,你应该知道 SPA 单页应用的 csrf 保护实现方式,你需要先请求 /sanctum/csrf-cookie 以获取 csrf token。
然后,我们请求 /login 路由,并将我们的 email 和 password 字段传递给后端接口处理。
现在让我们在 handleLogin() 方法中实现上面的需求:
handleLogin() { axios.get('/sanctum/csrf-cookie').then(response => { axios.post('/login', this.formData).then(response => { console.log('登录成功!'); }).catch(error => console.log(error)); // 如果验证不匹配 }); }
现在,使用当我们输入相应的信息你会发现流程已经走通。每个请求都会受到 csrf 保护,并发送登录接口所需要的 email 与 password 字段,即使现在没有响应数据,我的程序依然会通过 Promise 继续执行,而不会崩溃。
接下来要做什么?让我们完成登录操作吧!
用户检索
在我们的 Vue 组件中,继续创建名为 getSecrets() 方法,该方法是用户登陆成功之后,获取用户 secrets ,通常我们会得到一个 secrets 数组,之后我们将我们的得到的新的数组替换组件中原有的数组。
打当用户登录成功之后,我们调用 getSecrets() 函数以完成后续操作。
handleLogin() { axios.get('/sanctum/csrf-cookie').then(response => { axios.post('/login', this.formData).then(response => { this.getSecrets(); }).catch(error => console.log(error)); // credentials didn't match }); }, getSecrets() { axios.get('/api/secrets').then(response => this.secrets = response.data); }
但是,现在程序中我们返回的是所有用户 secrets。所以我们需要在 index() 方修改它,以得到正确的数据:
public function index(Request $request) { return $request->user()->secrets; }
在登录成功之后,所有需要用户验证的接口中的请求头中都会包含 laravel_session cookie,这样 Sanctum 可以通过该 cookie 来确定并关联当前请求的用户。
之后,既可以使用 $request 对象来获取用户的全部信息了,然后我们将 secret 信息与用户关联,并将数据返回。
最后我们将数据格式化、脱敏之后呈现给用户:
- created at
现在我们刷新应用,并使用我们 fake 的用户数据登录,就可以看到以下页面了:
至此,一个 SPA 单页应用的登录操作完成。
总结和后续
我仅仅刚开始接触并使用该扩展,如果使用以上方式验证用户,则之后所有需要用户信息的接口可以实现像传统 web 应用的登录操作一样,每个请求都会携带用户状态。
Of course, you can also use token tokens to implement authentication for SPA single-page applications, mobile and desktop applications. As the saying goes, all roads lead to Rome. This article is just a discussion and practice around the documentation extension.
I hope this article can bring convenience and inspiration to your development.
Recommended tutorial: "PHP Tutorial"
The above is the detailed content of Authorize Vue applications using Laravel Sanctum. For more information, please follow other related articles on the PHP Chinese website!