Nuxt称自己为直观的Vue框架。它的目标是在不牺牲性能或降低架构完整性的情况下,为开发者提供友好的体验。看到围绕VueJS的社区和工具的成长和发展是令人激动的--没有比现在更好的时机来开始这个生态系统了。
在本教程中,你将建立一个小型Web应用程序,从API中检索一些帖子,并为认证用户显示它们。对于认证,你将把Okta整合到你的Nuxt应用程序中。Okta的简单认证系统和Nuxt的强大功能意味着你可以在短短的时间内配置和设置你的认证。
你需要的东西
- 你喜欢的IDE(我将使用Visual Studio Code)。
- Node.js
- 一个Okta开发者账户
- Okta CLI工具
设置你的Okta应用程序
安装Okta CLI并运行okta login 。然后,运行okta apps create 。选择默认的应用程序名称,或者根据你的需要进行更改。 选择单页应用程序,然后按回车键。
在重定向URI中使用http://localhost:3000/login ,并将注销重定向URI设置为http://localhost:3000/ 。
Okta CLI是做什么的?
Okta CLI将在您的Okta机构中创建一个OIDC单页应用。它将添加您指定的重定向URI并授予Everyone组的访问权限。它还会为http://localhost:3000/ 添加一个受信任的来源。当它完成时,你会看到如下的输出。
Okta application configuration:
Issuer: https://dev-133337.okta.com/oauth2/default
Client ID: 0oab8eb55Kb9jdMIr5d6
注意:你也可以使用Okta管理控制台来创建你的应用程序。更多信息请参见创建一个Vue应用程序。
用Nuxt构建你的网络应用程序
如果你想使用已完成的项目进行跟踪,你可以在这里查看GitHub的仓库。
Nuxt提供了一个名为create-nuxt-app 的脚手架工具,使你的应用程序的脚手架变得简单。你可以运行以下命令来创建应用程序。
npx create-nuxt-app okta-vue-nuxt-example
通常情况下,任务运行器有几个选项。在使用这个任务运行器时,有一些重要的选项你应该看一下。
- 编程语言:JavaScript
- 包管理器:Npm
- UI框架:Bootstrap Vue
- Nuxt模块:Axios - 基于承诺的HTTP客户端
我们将使用Axios来获取我们应用程序中的数据。接下来,你可以选择你所选择的linting工具和一个测试框架。
- 渲染模式:通用(SSR/SSG)
- 部署目标:服务器(Node.js托管)。
你可以使用以下命令进入项目目录并运行该应用程序。
cd okta-vue-nuxt-example
npm run dev
如果你在浏览器中打开http://localhost:3000/,你会看到默认的Nuxt页面。

Nuxt项目的布局非常简单明了。首先你有一个.nuxt 文件夹,你编译的服务器代码将在这里结束。接下来是一个components 文件夹。在本教程中你不会用到这个文件夹,但在大型项目中,将页面分解成组件是常见的做法。这些组件可以在许多页面中重复使用。接下来,你会发现一个pages 文件夹,你的页面将放在这里。你的路线会被Nuxt从这些视图中推断出来。static 文件夹是你可以放置css、图片或其他静态内容来显示的地方。store目录包含你的Vuex商店文件。
以后你还会添加一个layouts 文件夹。 正如你可能已经猜到的,这个文件夹将包含布局。还有其他几个目录是为Nuxt开箱配置的,包括中间件、模块、插件和dist。 这些不在本文的讨论范围内,但知道它们的存在是很重要的。
最后,你将需要npm的两个包。第一个是@nuxtjs/dotenv ,这是一个nuxt友好的dotenv的实现。你将使用它来存储敏感信息,你不希望这些信息最终出现在你的源代码控制中。
最后,你将需要@nuxt/auth-next 来控制你的认证。
npm i @nuxtjs/dotenv@1.4.1
npm i @nuxtjs/auth-next@5.0.0-1637333559.35dbd53
安装好你的依赖项后,就可以开始构建你的应用程序了。首先,在你的根目录下添加一个新文件,命名为.env ,然后添加以下代码。
OKTA_DOMAIN=https://{yourOktaDomain}
OKTA_CLIENT_ID={yourClientId}
请确保用你的实际Okta信息替换占位变量。
现在打开位于根目录下的nuxt.config.js 文件,用以下代码替换其内容。
export default {
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: "todolist-article",
htmlAttrs: {
lang: "en",
},
meta: [
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },
{ hid: "description", name: "description", content: "" },
{ name: "format-detection", content: "telephone=no" },
],
link: [{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/bootstrap
"bootstrap-vue/nuxt",
// Doc: https://axios.nuxtjs.org/usage
"@nuxtjs/axios",
"@nuxtjs/dotenv",
"@nuxtjs/auth-next",
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {},
auth: {
strategies: {
okta: {
scheme: "openIDConnect",
endpoints: {
configuration: `${process.env.OKTA_DOMAIN}/oauth2/default/.well-known/oauth-authorization-server`,
logout: undefined,
},
clientId: process.env.OKTA_CLIENT_ID,
grantType: "authorization_code",
responseType: "code",
},
},
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
};
这个文件做的第一件事是使用dotenv。它通过任务运行器和npm来注册你之前添加的模块。最后,它为你的OAuth配置设置了选项。在这里,你可以使用你在.env 文件中设置的环境变量。
你应该注意到这行代码,即logout: undefined 。这对正确记录用户退出至关重要,因为Okta要求将idToken 作为一个查询参数传递。然而,nuxt-auth 不会在引擎盖下包括这个参数。解决方案是用undefined 覆盖从配置端点获得的注销URL,并在你的页面文件中手动注销用户。你很快就会实现这一点。
为了正确使用OAuth配置,Nuxt要求你在store 文件夹中添加一个文件,名为index.vue 。你可以让这个文件为空,但它必须存在,以便Nuxt使用它。如果你没有一个store 文件夹,现在就创建一个,并在其中添加一个空白的index.vue 文件。
添加你的Nuxt页面
现在,你可以开始添加页面到你的应用程序。Nuxt通过查看pages 文件夹来建立你的路线。你可以在他们的文档中阅读更多关于Nuxt的自定义路由的信息。
在处理你的页面之前,你应该设置好你的布局。在项目目录中添加一个名为layouts 的新文件夹,并添加一个名为default.vue 的文件。
这个文件,以及这个项目中的所有视图,都将使用Vue模板语法。Vue模板与大多数其他模板语法非常相似。它主要依靠v-bind HTML属性来处理事件或绑定属性值。你可以用v-on 语法来处理事件,它可以简称为@ ,如@click="doSomething" 。 b-* 组件来自Bootstrap Vue 库,该库应该已经通过npx task runner安装。
布局页面将显示页眉和页脚,并纳入一些分支逻辑,以确定用户是否应该看到login 或logout 按钮。它还包含一些常用的CSS和JavaScript,在每个使用布局的页面上都需要用到。这个页面上的<nuxt /> 元素将作为你页面上的代码的占位符。Nuxt会在这个部分渲染你的页面代码。
<template>
<div>
<b-container>
<b-navbar toggleable="lg" type="dark" variant="info">
<b-navbar-brand href="#">Posts</b-navbar-brand>
<b-navbar-nav>
<b-nav-item href="/dashboard"> Dashboard </b-nav-item>
</b-navbar-nav>
<b-navbar-nav v-if="loggedIn" class="ml-auto">
<b-button @click="logout" size="sm" class="my-2 my-sm-0" type="submit"
>Logout
</b-button>
</b-navbar-nav>
<b-navbar-nav v-else class="ml-auto">
<b-button @click="login" size="sm" class="my-2 my-sm-0" type="submit"
>Login
</b-button>
</b-navbar-nav>
</b-navbar>
<nuxt />
<footer id="sticky-footer" class="py-4 bg-dark text-white-50">
<div class="fluid-container footer">
<small>Copyright ©{{ year }} </small>
<br />
A small app built with
<a href="https://nuxtjs.org/" target="blank">Nuxt</a>, Protected by
<a href="https://www.okta.com/" target="blank">Okta</a>, Written by
<a href="https://profile.fishbowlllc.com" target="blank">Nik Fisher</a
>.
</div>
</footer>
</b-container>
</div>
</template>
<script>
export default {
data() {
return {
loggedIn: this.$auth.$state.loggedIn,
year: new Date().getFullYear(),
}
},
methods: {
logout() {
this.$auth.logout();
},
login() {
this.$auth.loginWith('okta').then(result => window.location = "/Dashboard");
}
},
}
</script>
<style scoped>
.fluid-container.footer > *:last-child {
margin-bottom: 0px;
color: #fff;
}
</style>
你还需要一个基本的登陆页面,不在认证范围内。你的登陆页面将提供一些关于应用程序的信息。它还将包含一个认证用户的重定向,将他们引导到Dashboard 页面。
打开pages 目录中的index.vue 页面,用下面的代码替换。
<template>
<div id="page-content">
<b-jumbotron
style="margin-top: 5vh"
header="Lets Get Some Posts"
lead="A Simple App with Nuxt and Okta"
>
<p>For more information visit their websites</p>
<b-button variant="primary" href="https://nuxtjs.org/" target="blank"
>Nuxt</b-button
>
<b-button
variant="outline-primary"
href="https://www.okta.com/"
target="blank"
>Okta</b-button
>
</b-jumbotron>
</div>
</template>
<script>
export default {
beforeMount() {
if (this.$auth.$state.loggedIn) window.location = '/Dashboard'
},
}
</script>
接下来,你可以添加Dashboard 页面。这个页面利用data() webhook,使用Axios从服务器上获取一些数据,然后显示在一个表中。Dashboard 页面还使用了auth 中间件来强制验证这个页面。当用户试图点击这个页面时,如果他们没有经过认证,他们将被转到你的登录页面。
在pages 文件夹中添加一个新文件,并将其命名为dashboard.vue 。将以下代码复制到你的dashboard.vue 文件中。
<template>
<div>
<b-table :items="posts" :fields="fields"> </b-table>
</div>
</template>
<script>
import Vue from 'vue'
export default Vue.extend({
middleware: ['auth'],
data() {
return {
fields: ['userId', 'title', 'body'],
posts: [],
}
},
async beforeMount() {
this.$axios
.$get('https://jsonplaceholder.typicode.com/posts')
.then((res) => {
this.posts = res
})
.catch((err) => {
console.log(err)
})
},
})
</script>
最后,你需要添加一个登录页面,Nuxt会将未认证的用户转到这个页面。在pages 文件夹中添加一个新的页面,命名为login.vue 。添加以下代码到其中。
<template>
<div id="page-content" class="p-4">
<a class="btn btn-primary" @click="$auth.loginWith('okta')">Login with Okta </a>
</div>
</template>
<script>
export default {
middleware: ['auth'],
data() {
return {}
},
beforeMount() {
if (this.$auth.$state.loggedIn) window.location = '/Dashboard'
}
}
</script>
测试你的Nuxt应用程序
现在你的应用程序已经完成了,你可以从你的终端运行npm run dev ,应用程序将建立。你应该先看到主页。

点击Dashboard或Login,这将把你引向Okta登录表。你可以在这里输入你的Okta凭证,你将被引导到Dashboard ,在那里你可以查看帖子。

用Nuxt和Vue做更多事情
只需一点点代码,你就可以把Nuxt和Okta结合起来,制作安全的Vue SPA或通用应用程序。你可以在GitHub上找到本教程中创建的例子的源代码。
在这篇文章中,你学到了如何使用@nuxt/auth-next 包来保护你的Nuxt应用程序使用Okta。你还学习了如何在Okta中创建应用程序并配置Vue应用程序来使用它。最后,你学会了如何使用@nuxtjs/axios 包来从样本API中提取数据。