Laravel8 Sanctum API认证+Vue问卷 搭建前后端分离SPA应用
1 Sanctum 扩展安装与配置
我们使用Sanctum 的身份验证功能为Vue前端提供API验证支持。
SPA 与 API 必须共享同一个顶级域名,但可以被放置在不同的子域名上,本项目前后端在同一顶级域名的两个子域。
- WNMP环境
phpstudy 8.1
- 项目目录
命令行工具建议使用windows PowerShell,比cmd更强大,兼容cmd的DOS命令集
PS D:\web_www> dir
目录: D:\web_www
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2022-03-12 18:44 api.laravel
d----- 2022-03-27 7:29 demand.vue
PS D:\web_www>
api.laravel 后端laravel项目目录
demand.vue 前端Vue问卷项目目录
- 前端
本地虚拟域名 demand.my.domain 或 127.0.0.1:8080
- 后端
本地虚拟域名 api.my.domain 或 127.0.0.1:8000
- laravel站点需要设置伪静态,在phpstudy网站->管理->伪静态中填写
try_files $uri u r i / / i n d e x . p h p ? uri/ /index.php? uri//index.php?query_string;
1.1 安装Sanctum
- 安装
在laravel项目目录安装sanctum
composer require laravel/sanctum
- 发布 Sanctum 的配置和迁移文件
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
- 数据迁移
php artisan migrate
PS D:\web_www\api.laravel>php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (34.38ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (29.99ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (28.26ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (54.88ms)
personal_access_tokens 表用于存放Api令牌
1.2 配置API中间件
将 Sanctum 的中间件添加到你应用的 app/Http/Kernel.php 文件中的 api 中间件组中,使api路由能够调用Sanctum进行身份验证
app/Http/Kernel.php
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
1.3 跨域访问配置
1.3.1 配置Sanctum跨域认证请求
如果本地开发使用VUE的127.0.0.1:8080的 URL 访问API,则应确保在域中包含8080端口号
config/sanctum.php
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort()
))),
Stateful的配置首选从env环境中提取参数,多个域名用逗号分隔,那我们就不修改这个配置文件,直接修改.env
SANCTUM_STATEFUL_DOMAINS = 127.0.0.1:8080
未设置SANCTUM_STATEFUL_DOMAINS,可能出现的报错信息
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/login' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我们在phpstudy中设置了虚拟域名demand.my.domain
SANCTUM_STATEFUL_DOMAINS = demand.my.domain
可能出现的报错
Access to XMLHttpRequest at 'http://api.my.domain/sanctum/csrf-cookie' from origin 'http://demand.my.domain' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- 解决办法:输入完整域名
SANCTUM_STATEFUL_DOMAINS = http://demand.my.domain
1.3.2 配置Laravel跨域访问
config/cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie'],
// 配置跨域支持的请求方式
'allowed_methods' => ['*'],
// 配置允许跨域访问的源,*表示全部允许
'allowed_origins' => ['*'],
// 正则匹配允许跨域访问的源
'allowed_origins_patterns' => [],
// 配置允许跨域的请求头
'allowed_headers' => ['*'],
// 自定义请求响应的Head信息
'exposed_headers' => [],
// 预检请求的有效时长
'max_age' => 0,
// 是否允许请求发送cookie
'supports_credentials' => true,
- 允许跨域的路由
‘paths’ => [‘api/*’, ‘sanctum/csrf-cookie’],- 允许发起的Http请求中带有验证凭证
‘supports_credentials’ => true,
1.3.3 配置Cookie会话域
支持同根域下的任何子域,如my.com根域名下自定义解析的www.my.com、spa.my.com、wj.my.com,这些子域名都能保持正常Cookie会话
config/session.php
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
session配置文件的domain使用环境变量值,我们可以直接在环境量中配置:
.env
SESSION_DOMAIN=.my.domain
2 问卷API框架
2.1 数据模型
2.1.1 用户模型
修改Laravel已经存在的用户模型app\Models\User.php
引入并使用Sanctum API 令牌验证模块HasApiTokens
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
/**
* The attributes that are mass assignable.
* 可批量填充的字段
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
* 模型转换为数组时应当隐藏的字段
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
* 数据库取出的字段属性转换成需要的数据类型
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
2.1.2 用户数据填充
修改用户数据工厂数据填充规则,修改默认用户密码 “my123456”
database\factories\UserFactory.php
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => bcrypt('my123456'),
//'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
设置自动生成10个用户(一般默认就是10)
database\seeders\DatabaseSeeder.php
\App\Models\User::factory(10)->create();
2.1.3 问卷题目模型
- 创建问卷模型、迁移文件、控制器
-m 自动创建迁