如何构建可投入生产的 Vue 身份验证 入门指南 使用 Amplify 编写代码(第二部分)——构建自定义身份验证流程。结论

2025-05-24

如何构建可用于生产的 Vue 身份验证

入门

使用 Amplify

编写代码

第 2 部分 - 构建自定义身份验证流程。

结论

使用 AWS 进行生产就绪的 Vue 身份验证

要随时查看该项目的最终代码,请单击此处

在本教程中,您将学习如何使用Vue RouterAWS AmplifyAmazon Cognito在您的 Vue 应用程序中构建真实的身份验证流程。虽然我们将使用的身份提供商是 AWS 和 Amazon Cognito,但我们应用程序的基本设计将与提供商无关,这意味着您应该能够使用您选择的提供商进行操作。

身份验证概述

如果您曾经尝试过推出自己的身份验证服务和实现(前端和后端),那么您已经意识到随之而来的痛苦。

值得庆幸的是,如今我们拥有众多出色的身份服务和提供商,可以为我们处理所有这些事务。您可能已经熟悉Auth0OktaAmazon Cognito等服务,它们在幕后完成了繁重的工作,因此您无需亲自实现用户和身份管理,而这却是大多数现代应用程序的必备功能。

在本教程中,您将学习如何管理用户注册、登录、忘记密码和 MFA 等所有流程。您还将学习如何使用 Vue Router 实现受保护的客户端路由,以便定义哪些路由可以公开,哪些路由需要仅对登录用户进行保护。

在本教程结束时,您将很好地掌握如何构建和部署启用企业级安全性和身份验证的 Vue 应用程序。

入门

创建 Vue 项目

我们要做的第一件事是使用 Vue CLI 搭建一个新的 Vue 应用程序。如果您尚未安装 Vue CLI,请点击此处按照安装说明进行操作。

~ vue create vue-auth

? Please pick a preset: default

cd vue-auth
Enter fullscreen mode Exit fullscreen mode

一旦项目创建完毕并且您进入目录,让我们使用 npm 或 yarn 安装我们需要的必要依赖项:

~ yarn add vue-router aws-amplify @aws-amplify/ui-vue
Enter fullscreen mode Exit fullscreen mode

什么是aws-amplify-vue?AWS Amplify 具有特定于平台的组件,使我们能够快速搭建并启动并运行重要功能,如身份验证流程、图像上传等。

创建文件夹结构

现在让我们创建用于实现身份验证流程的文件。在src目录中,创建以下文件:

~ touch router.js components/Auth.vue components/Home.vue components/Profile.vue components/Protected.vue
Enter fullscreen mode Exit fullscreen mode

使用 Amplify

安装 Amplify CLI

要添加身份验证服务,我们将使用 AWS Amplify CLI。现在就开始安装它吧:

~ npm install -g @aws-amplify/cli
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要配置 CLI。为此,请运行以下命令:

~ amplify configure
Enter fullscreen mode Exit fullscreen mode

有关如何配置 CLI 的完整演练,请观看视频。

现在我们已经创建了项目并安装了 CLI,接下来就可以创建要使用的身份验证服务了。为此,我们将初始化一个新的 Amplify 项目,然后为其添加身份验证功能。

初始化 Amplify 项目

要初始化新的 Amplify 项目,请运行以下init命令:

~ amplify init
Enter fullscreen mode Exit fullscreen mode

init将初始化项目并引导您完成一些步骤来配置项目名称、环境和其他构建设置。选择一个项目和环境名称,然后在其余问题中选择默认值。

添加身份验证服务

现在 Amplify 项目已经初始化,我们可以添加身份验证服务:

~ amplify add auth

? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings? No

~ amplify push
Enter fullscreen mode Exit fullscreen mode

默认安全配置将为我们提供此项目的智能默认值。如果您想要自定义配置,可以选择No,也可以稍后运行amplify update auth

成功运行后amplify push,身份验证已成功创建,我们现在可以开始编写代码!

您应该注意到,现在您的src目录中有一个名为aws-exports.js的文件(包含基本项目配置),并且您的根目录中有一个名为amplify的文件夹(包含详细的项目配置和自定义代码)。

编写代码

我们将通过两种方式实现身份验证:

  1. 第 1 部分 - 使用amplify-authenticatorAWS Amplify Vue 的预配置组件快速启动并运行我们的身份验证流程。
  2. 第 2 部分 - 构建完全自定义的身份验证流程。

第 1 部分 - 使用预配置amplify-authenticator组件

接下来,我们需要更新main.js 文件,以配置 Vue 项目,使其能够与 Amplify 和我们新的aws-exports.js文件协同工作。我们还需要让应用程序知道下一步将要创建的路由器。

src/main.js

// src/main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Amplify from 'aws-amplify'
import '@aws-amplify/ui-vue'
import config from './aws-exports';

import App from './App'
import router from './router'

Amplify.configure(config)
Vue.use(VueRouter)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  router
}).$mount('#app')
Enter fullscreen mode Exit fullscreen mode

接下来,我们将配置路由器。这里我们还会放置受保护路由的自定义逻辑。

src/router.js

// src/router.js
import VueRouter from 'vue-router'
import { Auth } from 'aws-amplify'

import Home from './components/Home'
import Profile from './components/Profile'
import AuthComponent from './components/Auth'
import Protected from './components/Protected'

const routes = [
  { path: '/', component: Home },
  { path: '/auth', component: AuthComponent },
  { path: '/protected', component: Protected, meta: { requiresAuth: true} },
  { path: '/profile', component: Profile, meta: { requiresAuth: true} }
]

const router = new VueRouter({
  routes
})

router.beforeResolve((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    Auth.currentAuthenticatedUser().then(() => {
      next()
    }).catch(() => {
      next({
        path: '/auth'
      });
    });
  }
  next()
})

export default router
Enter fullscreen mode Exit fullscreen mode
src/router.js 的详细信息
  1. 我们导入 Vue 和 VueRouter
  2. 我们导入路线中要用到的组件
  3. 我们定义了一个路由数组。我们添加了一个额外的元属性,使用名为 的布尔值来指定需要身份验证的路由requiresAuth
  4. 我们创建路由器变量
  5. 我们使用Vue Router 中的beforeResolve守卫(它会在导航确认之前被调用)来检查用户是否已通过身份验证。如果已通过身份验证,我们将允许他们进入下一个路由。如果未通过身份验证,我们将他们重定向到注册页面 ( /auth )。

接下来,让我们创建身份验证组件。

src/components/Auth.vue

// src/components/Auth.vue
<template>
  <div class="auth">
    <amplify-authenticator></amplify-authenticator>
  </div>
</template>

<script>

export default {
  name: 'auth'
}
</script>

<style>
.auth {
  margin: 0 auto;
  width: 460px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

src/components/Auth.vue 的详细信息

这是一个非常基础的组件,但实际上却功能强大!这个amplify-authenticatorVue 组件实际上会为我们搭建整个身份验证流程(注册、登录和忘记密码)。

现在我们将更新App组件。该组件将执行以下操作:

  1. 显示导航链接
  2. 渲染路由器
  3. 保存大部分用于监听用户登录/注销的身份验证逻辑。

src/App.vue

// src/App.vue
<template>
  <div id='app'>
    <div  class='nav'>
      <router-link tag="p" to="/">
        <a>Home</a>
      </router-link>
      <router-link tag="p" to="/profile">
        <a>Profile</a>
      </router-link>
      <router-link tag="p" to="/protected">
        <a>Protected</a>
      </router-link>
      <router-link tag="p" to="/auth" v-if="!signedIn">
        <a>Sign Up / Sign In</a>
      </router-link>
    </div>
    <router-view></router-view>
    <div class='sign-out'>
      <amplify-sign-out v-if="signedIn"></amplify-sign-out>
    </div>
  </div>
</template>

<script>
import { Auth, Hub } from 'aws-amplify'

export default {
  name: 'app',
  data() {
    return {
      signedIn: false
    }
  },
  beforeCreate() {
    Hub.listen('auth', data => {
      console.log('data:', data)
      const { payload } = data
      if (payload.event === 'signIn') {
        this.signedIn = true
        this.$router.push('/profile')
      }
      if (payload.event === 'signOut') {
        this.$router.push('/auth')
        this.signedIn = false
      }
    })
    Auth.currentAuthenticatedUser()
      .then(() => {
        this.signedIn = true
      })
      .catch(() => this.signedIn = false)
  }
}
</script>

<style>
.nav {
  display: flex;
}
.nav p {
  padding: 0px 30px 0px 0px;
  font-size: 18px;
  color: #000;
}
.nav p:hover {
  opacity: .7;
}
.nav p a {
  text-decoration: none;
}
.sign-out {
  width: 160px;
  margin: 0 auto;
}
</style>
Enter fullscreen mode Exit fullscreen mode

src/components/App.vue 的详细信息

  1. 如果用户已登录,我们将使用该amplify-sign-out组件来呈现退出按钮。
  2. 我们创建一个名为的布尔值signedIn,并在应用程序加载时将其设置为 false
  3. 在生命周期方法中,我们使用APIbeforeCreate监听事件。如果检测到登录,我们会将其重定向至查看个人资料,并设置为 true。如果检测到退出,我们会将其重定向至路由,并设置为 false。authStateHubsignedIn/authsignedIn
  4. 当应用程序加载时,我们还会调用来Auth.currentAuthenticatedUser检查用户是否已登录并signedIn适当地设置变量。

接下来,让我们添加Profile组件。

这个基本组件将显示我们将使用 Amplify 检索的用户名。

src/components/Profile.vue

// src/components/Profile.vue
<template>
  <h1>Welcome, {{user.username}}</h1>
</template>

<script>
import { Auth } from 'aws-amplify'

export default {
  name: 'Profile',
  data() {
    return {
      user: {}
    }
  },
  beforeCreate() {
    Auth.currentAuthenticatedUser()
      .then(user => {
        this.user = user
      })
      .catch(() => console.log('not signed in...'))
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

src/components/Profile.vue 的详细信息

关于此组件,需要注意的一点是,我们通过调用该Auth.currentAuthenticatedUser方法来检索用户信息。该方法将返回一个user包含已登录用户元数据的对象,如果用户未登录,则会出错。

现在我们可以创建最后两个基本组件。

src/components/Home.vue

// src/components/Home.vue
<template>
  <h1>Home</h1>
</template>

<script>
export default {
  name: 'home',
}
</script>
Enter fullscreen mode Exit fullscreen mode

src/组件/受保护的.vue

// src/components/Protected.vue
<template>
  <h1>Hello from protected route!</h1>
</template>

<script>

export default {
  name: 'protected',
}
</script>
Enter fullscreen mode Exit fullscreen mode

测试一下

我们的应用程序的第 1 部分已经完成,让我们测试一下:

~ npm run serve
Enter fullscreen mode Exit fullscreen mode

当应用加载时,我们应该只能查看Home路由。如果我们尝试导航到某个受保护的路由,我们应该被重定向到身份验证屏幕。

一旦我们登录,我们就应该能够查看受保护的页面。

您会注意到用户信息已被持久化。这由 Amplify 客户端库为您处理。要退出,您必须明确点击我们渲染的退出按钮,或使用Auth.signOutAuth 类别中的方法。

现在我们已经启动并运行了,下一步是什么?好吧,amplify-authenticator组件可以在一定程度上进行自定义,以控制渲染的字段以及样式(要了解如何操作,请查看此处的文档)。但是,如果我们想要一个完全自定义的身份验证流程呢?我们现在就开始吧。

第 2 部分 - 构建自定义身份验证流程。

现在身份验证已经正常工作,接下来让我们更新一些功能,使其能够自定义。目前,我们所有的身份验证功能都存储在Auth.vue中。在这个文件中,我们使用该amplify-authenticator组件搭建整个身份验证流程。接下来,让我们更新应用,使其支持自定义身份验证。

我们需要做的第一件事是在我们的组件目录中创建几个新文件,一个用于登录用户,一个用于注册新用户。

touch src/components/SignIn.vue src/components/SignUp.vue
Enter fullscreen mode Exit fullscreen mode

接下来,让我们更新Auth.vue以使用新文件并添加一些新功能。在此文件中,我们将根据某些组件状态渲染SignUpSignIn组件。我们还将渲染一个链接,允许我们在注册和登录状态之间切换:

src/components/Auth.vue

// src/components/Auth.vue
<template>
  <div class="auth">
    <sign-up :toggle='toggle' v-if="formState === 'signUp'"></sign-up>
    <sign-in v-if="formState === 'signIn'"></sign-in>
    <p v-on:click="toggle" class="toggle">{{ formState === 'signUp' ?
      'Already sign up? Sign In' : 'Need an account? Sign Up'
      }}</p>
  </div>
</template>

<script>
import SignUp from './SignUp'
import SignIn from './SignIn'

export default {
  name: 'app',
  data() {
    return {
      formState: 'signUp'
    }
  },
  methods: {
    toggle() {
      this.formState === 'signUp' ? this.formState = 'signIn' : this.formState = 'signUp'
    }
  },
  components: {
    SignUp,
    SignIn
  }
}
</script>

<style>
.auth {
  margin: 0 auto;
  width: 460px;
}
.toggle {
  cursor: pointer;
  font-size: 18px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

src/components/Auth.vue 的详细信息

这里主要考虑的是,我们导入了两个新组件,并根据formState布尔值来渲染它们。目前还没有什么特别有趣的事情。

接下来,让我们创建注册表。

src/components/SignUp.vue

// src/components/SignUp.vue
<template>
  <div>
    <h2>{{ formState === 'signUp' ? 'Sign Up' : 'Confirm Sign Up' }}</h2>
    <div class='formcontainer' v-if="formState === 'signUp'">
      <input placeholder="username" v-model='form.username' class='input' />
      <input placeholder="password" type='password' v-model='form.password' class='input' />
      <input placeholder="email" v-model='form.email' class='input' />
      <button v-on:click='signUp' class='button'>Sign Up</button>
    </div>
    <div class='formcontainer' v-if="formState === 'confirmSignUp'">
      <input placeholder="confirmation code" v-model='form.authCode' class='input' />
      <button v-on:click='confirmSignUp' class='button'>Confirm Sign Up</button>
    </div>
  </div>
</template>

<script>
import { Auth } from 'aws-amplify'

export default {
  name: 'home',
  props: ['toggle'],
  data() {
    return {
      formState: 'signUp',
      form: {
        username: '',
        password: '',
        email: ''
      }
    }
  },
  methods: {
    async signUp() {
      const { username, password, email } = this.form
      await Auth.signUp({
        username, password, attributes: { email }
      })
      this.formState = 'confirmSignUp'
    },
    async confirmSignUp() {
      const { username, authCode } = this.form
      await Auth.confirmSignUp(username, authCode)
      alert('successfully signed up! Sign in to view the app.')
      this.toggle()
    }
  }
}
</script>

<style>
.formcontainer {
  display: flex;
  flex-direction: column;
  width: 500px;
  margin: 0 auto;
}
.input {
  margin-bottom: 7px;
  height: 38px;
  border: none;
  outline: none;
  border-bottom: 2px solid #ddd;
  font-size: 20px;
}
.button {
  height: 45px;
  border: none;
  outline: none;
  background-color: #dddddd;
  margin-top: 8px;
  cursor: pointer;
  font-size: 18px;
}
.button:hover {
  opacity: .7
}
</style>
Enter fullscreen mode Exit fullscreen mode

src/components/SignUp.vue 的详细信息

  1. 我们有两个单独的表格 - 一个用于注册,一个用于确认注册(MFA 确认)
  2. 我们有一个formState布尔值,我们将使用它在两种形式之间切换。
  3. 我们的数据对象上有一个表单属性,当新用户注册时,它将跟上username、、password& 的步伐。email
  4. signUp方法调用 AmplifyAuth.signUp方法,传入表单属性。
  5. confirmSignUp方法调用 AmplifyAuth.confirmSignUp方法,并传入username& authCode。用户成功注册后,我们将切换视图以显示SignUp组件。

最后,我们来看看SignIn组件。该组件与SignUp非常相似,因为它也有一个表单,并且调用了 AmplifyAuth类的一个方法。

src/components/SignIn.vue

// src/components/SignIn.vue
<template>
  <div>
    <h2>Sign In</h2>
    <div class='formcontainer'>
      <input placeholder="username" v-model='form.username' class='input' />
      <input placeholder="password" type='password' v-model='form.password' class='input' />
      <button v-on:click='signIn' class='button'>Sign In</button>
    </div>
  </div>
</template>

<script>
import { Auth } from 'aws-amplify'
export default {
  name: 'home',
  data() {
    return {
      form: {
        username: '',
        password: ''
      }
    }
  },
  methods: {
    async signIn() {
      const { username, password } = this.form
      await Auth.signIn(username, password)
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

src/components/SignIn.vue 的详细信息

  1. 我们有一个允许用户登录的表单
  2. 我们通过调用 Amplify 方法登录用户Auth.signIn
  3. App.vue中,我们正在监听事件signIn,用户成功登录后将被路由到Profile路由。

测试一下

我们的应用程序的第 2 部分已经完成,让我们尝试一下吧!

~ npm run serve
Enter fullscreen mode Exit fullscreen mode

您现在应该看到您的应用程序加载了我们创建的新注册/登录表单。

后续步骤

Amplify Auth 类30 多种不同的方法,包括forgotPasswordsetPreferredMFA、 &signOut等。使用这些方法,您可以继续定制身份验证流程,使其更加健壮。

我们使用的样式很少,以防止这篇已经很长的博客文章过于冗长,但由于您可以完全控制身份验证流程,因此您可以根据自己的喜好设置样式。

Amplify 身份验证还支持 Facebook、Twitter、Google 和 Amazon 等提供商的联合登录。如需了解更多信息,请查看此处的文档。

结论

要查看最终的 repo 和源代码,请单击此处

要了解有关 Amplify 的更多信息,请查看此处的文档

还可以查看Awesome AWS Amplify Repo以获取更多教程和入门项目。

我叫Nader Dabit。我是 Amazon Web Services 的开发倡导者,负责 AWS AppSync 和 AWS Amplify 等项目。我还擅长跨平台应用程序开发。

文章来源:https://dev.to/dabit3/how-to-build-production-ready-vue-authentication-23mk
PREV
如何以开发者身份进入加密货币领域
NEXT
GraphQL 教程 - 如何使用 AWS AppSync 和 AWS Amplify 管理图像和文件的上传和下载