Sanctum 已经配置了,那么现在就做一个单页面,来进行测试。主要是做登录、注册的调用。这里使用 vue3。这里仅仅是测试,不作为项目代码的一部分,可以理解为是一个单独项目,但是调用的接口是项目文件里构建的。
新建 vue3 项目
# 创建项目
pnpm create vue
#配置如下图所示
# 不要 ts
# 也不要支持 jsx
# 需要 router
# 需要 pinia
# 许愿单元测试
# 不需要端到端测试
# 需要 eslint检查
# 需要美丽的格式化代码

然后执行下边命令,把项目运行起来
cd yuepaibao
pnpm install
pnpm format
pnpm dev
在浏览器中打开 http://localhost:5173/ 就可以访问到站点了。看到效果了。
我们养成好习惯,把代码添加到版本控制中。
git init -b main
git add .
git commit -m 'vue3 initialize'
对 eslint 和 prettier 进行配置
配置 eslint,修改 .eslintrc.cjs 文件
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
    root: true,
    extends: [
        './.eslintrc-auto-import.json',
        'plugin:vue/vue3-essential',
        'eslint:recommended',
        '@vue/eslint-config-prettier'
    ],
    parserOptions: {
        ecmaVersion: 'latest'
    },
    rules: {
        'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
        'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
        'comma-dangle': 0,
        'vue/multi-word-component-names': 'off',
        semi: ['warn', 'never']
    }
}
comma-dangle 为0,禁止在数据的尾部追随逗号
semi: ['warn', 'never'] 禁止尾部使用分号
'vue/multi-word-component-names': 'off' 允许组件命名为单个单词。比如 header.vue。
配置 prettier,修改 .prettierrc.json 文件
{
    "printWidth": 120,
    "tabWidth": 2,
    "useTabs": true,
    "semi": false,
    "singleQuote": true,
    "quoteProps": "as-needed",
    "bracketSpacing": true,
    "bracketSameLine": true,
    "arrowParens": "always",
    "vueIndentScriptAndStyle": false,
    "endOfLine": "auto",
    "trailingComma": "none"
}
整理页面
安装 sass
pnpm add -D sass
去掉不需要组件页面,删除main.css 和 base.css。再重新建立一个 main.scss 文件。到此,只有一个干净的 App.vue 文件和 main.scss 文件。这个时候肯定会报错的。我们接着整。
我们新建以下几个页面(习惯把公用的组件成为组件,其他的叫页面)。
.
├── home
│   └── index.vue
├── layouts
│   ├── footer.vue
│   └── header.vue
└── user
    ├── login.vue
    └── register.vue
然后,往里边加一些简单代码。如下:
header.vue
<template>
    <header>
      <h2>this is header</h2>
    </header>
  </template>
  <script setup>
  </script>
  <style lang="scss" scoped>
  header {
      display: flex;
      box-sizing: border-box;
      padding: 0 30px;
      width: 100%;
      height: 72px;
      background-color: #fff;
      box-shadow: 0 .125rem .25rem #00000013!important;
  }
  </style>
footer.vue
<template>
  <footer>
    <h2>this is footer</h2>
  </footer>
</template>
<script setup>
</script>
<style lang="scss" scoped>
footer {
    display: flex;
    width: 100%;
    height: 220px;
    background-color: #383838;
    box-sizing: border-box;
    padding: 0 30px;
    h2 {
        color: #fff;
    }
}
</style>
home.vue
<template>
  <div class="container">
    <h2>this is home</h2>
  </div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.container {
    box-sizing: border-box;
    padding: 0 30px;
}
</style>
login.vue
<template>
  <div class="">login</div>
</template>
<script setup>
</script>
<style lang="scss" scoped></style>
register.vue
<template>
  <div class="">register</div>
</template>
<script setup>
</script>
<style lang="scss" scoped></style>
然后修改 router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/home/index.vue'
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/login',
      name: 'login',
      component: () => import('../views/user/login.vue')
    },
    {
      path: '/register',
      name: 'register',
      component: () => import('../views/user/register.vue')
    }
  ]
})
export default router
修改 App.vue,配合创建的这些页面
<script setup>
import { RouterView } from 'vue-router'
import Header from '@/views/layouts/header.vue'
import Footer from '@/views/layouts/footer.vue'
</script>
<template>
  <div class="main">
    <Header />
    <RouterView />
  </div>
  <Footer />
</template>
<style scoped>
</style>
最后修改 main.js,引入 css 改为引入 scss。就是文件名改一下。main.scss 填入以下 code。
html,body {
    margin: 0;
    padding: 0;
}
#app {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    min-height: 100vh;
    .main {
        display: flex;
        flex-direction: column;
        flex:1;
    }
}
这样,一个基本的架构页面就出来了。如下图:

好了,提交代码。
git add .
git commit -m '构建基础页面'
下一步,就是找一个好看的 ui 库。写登录和注册表单逻辑。 elemeui 看多了,and design 也看多了,这里用 naiveui。好就这样。
bootstrap 脚手架带了登录注册相关的页面和逻辑。这里来测测。然后使用 Sanctum 来处理授权相关的逻辑。它不仅可以处理 web 页面的请求,还可以使用令牌的方式来处理api请求 。
这里是一个提供多平台服务的项目。有来自 app,多家小程序的接口请求,也有后台页面(单spa页面)的请求,还有基于官网的请求。所以 Sanctum 是一个很好的选择
.env 文件中配置好了数据库的信息,并且也创建了数据库后
# 执行迁移生成对应的数据表
php artisan migrate 
打开首页,点击注册页面。输入对应信息,点击注册。成功后会重定向到 /home uri 下。只是,我们之前删除了 home 路由。修改登录后重定向的地址就可以正确重定向了。
# app/Providers/RouteServiceProvider.php
# 修改(之前是 public const HOME = '/home';)
public const HOME = '/';


以上是 laravel 的默认认证方式。还有截图看到的注册页面,在 container 样式后边加了一个 mt-4。因为 app.blade.php 中是没有任何间隙的。
以上只是一个演示。下边就所有的用户认证都用 sanctum 处理。
sanctum 阶段
官网文档: https://laravel.com/docs/10.x/sanctum
laravel10 默认已经安装了 Sanctum 。我们只需要使用 vendor:publish 来发布 Sanctum 的配置和迁移文件。
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
其实,默认已经创建了的。
修改 config/auth.php
我们先在 config/auth.php  增加一个 'api' 的守护,这个是给app、小程序这些接口适用的。默认的 'web'  这个是给 web 页面和后台共同使用的,他们公用 cookie,并且支持 csrf 验证。 后台也是通过接口的方式进行调用的。只是这种方式限定了后台的主域和网站的主域要一致。
    'guards' => [
        //原来的
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        // 新增的
        'api' => [
            'driver' => 'sanctum',
            'provider' => 'users',
            'hash' => false,
        ]
    ],
修改 .env.example
在末尾追加配置
# .env.example 文件,参与版本控制
# sanctum 白名单
SANCTUM_STATEFUL_DOMAINS=
同样,在 .env 末尾也追加配置
# sanctum 白名单
SANCTUM_STATEFUL_DOMAINS=.xr.com
修改 app/Http/Kernel.php
$middlewareGroups 修改。
…
        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
$middlewareAliases 修改,在末尾追加下边两个配置。这个不是必须的,有用到就配置。
    protected $middlewareAliases = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        …
        'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
        'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
增加路由服务的配置
修改  app/Providers/RouteServiceProvider.php, 在 boot 中增加一个后台的配置。修改 api 接口的配置。后台将使用 vue 或 react 做成前 spa 页面。将使用前后端分离的方式。这里虽然看起来是一起,在 nginx 中,会做处理。
            Route::prefix('admin/api')
                ->middleware('web')
                ->group(base_path('routes/admin.php'));
然后,在 routes 文件夹下,增加一个 admin.php 的路由控制文件。
最后对 User 模型进行配置
在 app/Models/User.php 中增加
protected $guard_name = 'web';
其实,默认就是的了。这里可以不要。如果配置改名了,这里就得用上了。
到此,基于网站的,以及基于后台的(接口),还有基于app,小程序的(接口)用户认证已经配置完成了。
# 网站
ypb2.com
# 后台
ypb2.com/admin/api
# app、小程序接口
ypb2.com/api
后边,将对这三种情景进行测试和验证。
laravel10 + bootstrap5 自适应站点[3] 是多余的,是临时看到一个赏析悦目的站点的一个冲动。还是回到正常的思路上来。我们这里先完成一个 loading 的功能。这里使用 nprogress。
开始吧
# 安装
pnpm add nprogress
# 配置 css (resources/sass/app.scss),加入以下代码
@import "nprogress/nprogress.css";
/* Loading 颜色 */
#nprogress .bar {
    background: $primary-color !important;
}
# 配置 js (resources/js/app.js),加入一下代码
import NProgress from "nprogress";
// 进度条
NProgress.configure({ showSpinner: false });
NProgress.start();
window.onload = () => {
    NProgress.done();
}
# 编译
pnpm run build
到此,配置和使用完毕。刷新页面,就可以在顶部看到 loading 的效果了。这是一个粗略简单的效果。其实,就想要这种简单多的就好。
提交代码
git add .
git commit -m '创建页面 loading nprogress'
