okta使用

tech2022-09-06  113

okta使用

This article was originally published on the Okta developer blog. Thank you for supporting the partners who make SitePoint possible.

本文最初发布在Okta开发人员博客上 。 感谢您支持使SitePoint成为可能的合作伙伴。

I’ve danced the JavaScript framework shuffle for years starting with jQuery, then on to Angular. After being frustrated with Angular’s complexity, I found React and thought I was in the clear. What seemed simple on the surface ended up being a frustrating mess. Then I found Vue.js. It just felt right. It worked as expected. It was fast. The documentation was incredible. Templating was eloquent. There was a unanimous consensus around how to handle state management, conditional rendering, two-way binding, routing, and more.

从jQuery开始,到Angular,我已经对JavaScript框架改组已经进行了很多年。 在对Angular的复杂性感到沮丧之后,我找到了React,并以为我很清楚。 表面上看似简单的事情最终变成了令人沮丧的混乱。 然后我找到了Vue.js。 感觉还不错。 它按预期工作。 很快 该文档令人难以置信。 模板雄辩。 关于如何处理状态管理,条件渲染,双向绑定,路由等等,存在一致的共识。

This tutorial will take you step by step through scaffolding a Vue.js project, offloading secure authentication to Okta’s OpenID Connect API (OIDC), locking down protected routes, and performing CRUD operations through a backend REST API server. This tutorial uses the following technologies but doesn’t require intimate knowledge to follow along:

本教程将逐步指导您完成Vue.js项目,将安全认证转移到Okta的OpenID Connect API(OIDC) ,锁定受保护的路由以及通过后端REST API服务器执行CRUD操作的步骤。 本教程使用以下技术,但不需要任何专业知识:

Vue.js with vue-cli, vue-router, and Okta Vue SDK

带有vue-cli , vue-router和Okta Vue SDK的 Vue.js

Node with Express, Okta JWT Verifier, Sequelize, and Epilogue

Express , Okta JWT Verifier , Sequelize和Epilogue的节点

关于Vue.js (About Vue.js)

Vue.js is a robust but simple Javascript framework. It has one of the lowest barriers to entry of any modern framework while providing all the required features for high performance web applications.

Vue.js是一个健壮但简单的Javascript框架。 它是所有现代框架进入的最低障碍之一,同时为高性能Web应用程序提供了所有必需的功能。

This tutorial covers two primary builds, a frontend web app and backend REST API server. The frontend will be a single page application (SPA) with a homepage, login and logout, and a posts manager.

本教程涵盖两个主要构建,一个前端Web应用程序和一个后端REST API服务器。 前端将是一个具有主页,登录和注销以及帖子管理器的单页应用程序(SPA)。

Okta’s OpenID Connect (OIDC) will handle our web app’s authentication through the use of Okta’s Vue SDK. If an unauthenticated user navigates to the posts manager, the web app should attempt to authenticate the user.

Okta的OpenID Connect(OIDC)将通过使用Okta的Vue SDK处理我们的Web应用程序的身份验证。 如果未经身份验证的用户导航到帖子管理器,则Web应用程序应尝试对用户进行身份验证。

The server will run Express with Sequelize and Epilogue. At a high level, with Sequelize and Epilogue you can quickly generate dynamic REST endpoints with just a few lines of code.

该服务器将运行带有Sequelize和Epilogue的 Express 。 在较高的层次上,使用Sequelize和Epilogue,您只需几行代码即可快速生成动态REST端点。

You will use JWT-based authentication when making requests from the web app and Okta’s JWT Verifier in an Express middleware to validate the token. Your app will expose the following endpoints which all require requests to have a valid access token.

从Web应用程序和Express中间件中的Okta的JWT验证程序发出请求以验证令牌时,将使用基于JWT的身份验证。 您的应用程序将公开以下端点,所有这些端点均要求请求具有有效的访问令牌。

- GET /posts - GET /posts/:id - POST /posts - PUT /posts/:id - DELETE /posts/:id

创建您的Vue.js应用 (Create Your Vue.js App)

To get your project off the ground quickly you can leverage the scaffolding functionality from vue-cli. For this tutorial, you are going to use the progressive web app (PWA) template that includes a handful of features including webpack, hot reloading, CSS extraction, and unit testing.

为了快速启动您的项目,您可以利用vue-cli的脚手架功能。 在本教程中,您将使用渐进式Web应用程序(PWA)模板 ,其中包括一些功能,包括webpack , 热重载 ,CSS提取和单元测试。

If you’re not familiar with the tenets of PWA, check out our ultimate guide to progressive web applications.

如果您不熟悉PWA的宗旨,请查看我们有关渐进式Web应用程序的最终指南 。

To install vue-cli run:

要安装vue-cli运行:

npm install -g vue-cli

Next, you need to initialize your project. When you run the vue init command just accept all the default values.

接下来,您需要初始化您的项目。 运行vue init命令时,只需接受所有默认值即可。

vue init pwa my-vue-app cd ./my-vue-app npm install npm run dev

Point your favorite browser to http://localhost:8080 and you should see the fruits of your labor:

将您喜欢的浏览器指向http://localhost:8080 ,您应该看到自己的工作成果:

Extra Credit: Check out the other templates available for vue-cli.

额外的信用 :查看适用于vue-cli的其他模板 。

安装引导程序 (Install Bootstrap)

Let’s install bootstrap-vue so you can take advantage of the various premade components (plus you can keep the focus on functionality and not on custom CSS):

让我们安装bootstrap-vue,以便您可以利用各种预制组件 (此外,您可以专注于功能而不是自定义CSS):

npm i --save bootstrap-vue bootstrap

To complete the installation, modify ./src/main.js to include bootstrap-vue and import the required CSS files. Your ./src/main.js file should look like this:

要完成安装,请修改./src/main.js以包括bootstrap-vue并导入所需CSS文件。 您的./src/main.js文件应如下所示:

// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import BootstrapVue from 'bootstrap-vue' import 'bootstrap/dist/css/bootstrap.css' import 'bootstrap-vue/dist/bootstrap-vue.css' Vue.use(BootstrapVue) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: { App } })

使用Okta添加身份验证 (Add Authentication with Okta)

Dealing with authentication in a web app is the bane of every developer’s existence. That’s where Okta comes in to secure your web applications with minimal code. To get started, you will need to create an OIDC application in Okta. Sign up for a forever-free developer account (or log in if you already have one).

在Web应用程序中处理身份验证是每个开发人员生存的祸根。 那就是Okta用最少的代码保护您的Web应用程序安全的地方。 首先,您需要在Okta中创建一个OIDC应用程序。 注册一个永久免费的开发者帐户 (如果已有,请登录)。

Once logged in, create a new application by clicking “Add Application”.

登录后,单击“添加应用程序”创建一个新的应用程序。

Select the “Single-Page App” platform option.

选择“单页应用”平台选项。

The default application settings should be the same as those pictured.

默认的应用程序设置应与图片相同。

To install the Okta Vue SDK, run the following command:

要安装Okta Vue SDK,请运行以下命令:

npm i --save @okta/okta-vue

Open ./src/router/index.js and replace the entire file with the following code.

打开./src/router/index.js并将整个文件替换为以下代码。

import Vue from 'vue' import Router from 'vue-router' import Hello from '@/components/Hello' import PostsManager from '@/components/PostsManager' import Auth from '@okta/okta-vue' Vue.use(Auth, { issuer: 'https://{yourOktaDomain}.com/oauth2/default', client_id: '{yourClientId}', redirect_uri: 'http://localhost:8080/implicit/callback', scope: 'openid profile email' }) Vue.use(Router) let router = new Router({ mode: 'history', routes: [ { path: '/', name: 'Hello', component: Hello }, { path: '/implicit/callback', component: Auth.handleCallback() }, { path: '/posts-manager', name: 'PostsManager', component: PostsManager, meta: { requiresAuth: true } } ] }) router.beforeEach(Vue.prototype.$auth.authRedirectGuard()) export default router

You’ll need to replace {yourOktaDomain} and {yourClientId} which can be found on your application overview page in the Okta Developer Console. This will inject an authClient object into your Vue instance which can be accessed by calling this.$auth anywhere inside your Vue instance.

您需要替换{yourOktaDomain}和{yourClientId} ,它们可以在Okta开发者控制台的应用程序概述页面上找到。 这会将authClient对象注入到Vue实例中,可以通过在Vue实例内的任何位置调用this.$auth来访问该对象。

Vue.use(Auth, { issuer: 'https://{yourOktaDomain}.com/oauth2/default', client_id: '{yourClientId}', redirect_uri: 'http://localhost:8080/implicit/callback', scope: 'openid profile email' })

The final step of Okta’s authentication flow is redirecting the user back to your app with the token values in the URL. The Auth.handleCallback() component included in the SDK handles the redirect and persists the tokens on the browser.

Okta身份验证流程的最后一步是使用URL中的令牌值将用户重定向回您的应用。 SDK中包含的Auth.handleCallback()组件可处理重定向并在浏览器中保留令牌。

{ path: '/implicit/callback', component: Auth.handleCallback() }

You also need to lock down protected routes from being accessed by unauthenticated users. This is accomplished by implementing a navigation guard. As the name suggests, navigation guards are primarily used to guard navigations either by redirecting or canceling.

您还需要锁定未经保护的路由,以防止未经身份验证的用户访问。 这可以通过实现导航卫士来实现。 顾名思义, 导航卫士主要用于通过重定向或取消来保护导航。

The SDK comes with the method auth.authRedirectGuard() that checks matched routes’ metadata for the key requiresAuth and redirects the user to the authentication flow if they are not authenticated.

该SDK自带的方法auth.authRedirectGuard()支票匹配路由的元数据的键requiresAuth并且如果它们不认证的用户重定向至身份验证流程。

router.beforeEach(Vue.prototype.$auth.authRedirectGuard())

With this navigation guard installed, any route that has the following metadata will be protected.

安装此导航保护后,具有以下元数据的任何路线都将受到保护。

meta: { requiresAuth: true }

在Vue中自定义您的应用布局 (Customize Your App Layout in Vue)

The web app’s layout is located in a component ./src/App.vue. You can use the router-view component to render the matched component for the given path.

Web应用程序的布局位于组件./src/App.vue 。 您可以使用router-view组件来呈现给定路径的匹配组件。

For the main menu, you’ll want to change the visibility of certain menu items based on the status of the activeUser:

对于主菜单,您将需要根据activeUser的状态更改某些菜单项的可见性:

Not Authenticated: Show only Login

未验证:仅显示登录

Authenticated: Show only Logout

已验证:仅显示注销

You can toggle the visibility of these menu items using the v-if directive in Vue.js that checks the existence of activeUser on the component. When the component is loaded (which calls created()) or when a route changes we want to refresh the activeUser.

您可以使用Vue.js中的v-if指令切换这些菜单项的可见性,该指令检查组件上是否存在activeUser 。 加载组件时(调用created() )或更改路线时,我们要刷新activeUser 。

Open ./src/App.vue and copy/paste the following code.

打开./src/App.vue并复制/粘贴以下代码。

<template> <div id="app"> <b-navbar toggleable="md" type="dark" variant="dark"> <b-navbar-toggle target="nav_collapse"></b-navbar-toggle> <b-navbar-brand to="/">My Vue App</b-navbar-brand> <b-collapse is-nav id="nav_collapse"> <b-navbar-nav> <b-nav-item to="/">Home</b-nav-item> <b-nav-item to="/posts-manager">Posts Manager</b-nav-item> <b-nav-item href="#" @click.prevent="login" v-if="!activeUser">Login</b-nav-item> <b-nav-item href="#" @click.prevent="logout" v-else>Logout</b-nav-item> </b-navbar-nav> </b-collapse> </b-navbar> <!-- routes will be rendered here --> <router-view /> </div> </template> <script> export default { name: 'app', data () { return { activeUser: null } }, async created () { await this.refreshActiveUser() }, watch: { // everytime a route is changed refresh the activeUser '$route': 'refreshActiveUser' }, methods: { login () { this.$auth.loginRedirect() }, async refreshActiveUser () { this.activeUser = await this.$auth.getUser() }, async logout () { await this.$auth.logout() await this.refreshActiveUser() this.$router.push('/') } } } </script>

Every login must have a logout. The following snippet will logout your user, refresh the active user (which is now null), and then redirect the user to the homepage. This method is called when a user clicks on the logout link in the nav.

每次登录都必须注销。 以下代码段将注销您的用户,刷新活动用户(现在为null),然后将用户重定向到首页。 当用户单击导航中的注销链接时,将调用此方法。

async logout () { await this.$auth.logout() await this.refreshActiveUser() this.$router.push('/') }

Components are the building blocks within Vue.js. Each of your pages will be defined in the app as a component. Since the vue-cli webpack template utilizes vue-loader, your component source files have a convention that separates template, script, and style (see here).

组件是Vue.js中的构建块。 您的每个页面都将在应用程序中定义为组件。 由于vue-cli Webpack模板使用vue-loader ,因此组件源文件具有将模板,脚本和样式分开的约定( 请参见此处 )。

Now that you’ve added vue-bootstrap, modify ./src/components/Hello.vue to remove the boilerplate links vue-cli generates.

现在,您已经添加了vue-bootstrap,修改./src/components/Hello.vue以删除vue-cli生成的样板链接。

<template> <div class="hero"> <div> <h1 class="display-3">Hello World</h1> <p class="lead">This is the homepage of your vue app</p> </div> </div> </template> <style> .hero { height: 90vh; display: flex; align-items: center; justify-content: center; text-align: center; } .hero .lead { font-weight: 200; font-size: 1.5rem; } </style>

At this point you can stub out the Post Manager page to test your authentication flow. Once you confirm authentication works, you’ll start to build out the API calls and components required to perform CRUD operations on your Posts model.

此时,您可以将“邮递管理器”页面存根,以测试身份验证流程。 确认身份验证成功后,您将开始构建在Posts模型上执行CRUD操作所需的API调用和组件。

Create a new file ./src/components/PostsManager.vue and paste the following code:

创建一个新文件./src/components/PostsManager.vue并粘贴以下代码:

<template> <div class="container-fluid mt-4"> <h1 class="h1">Posts Manager</h1> <p>Only authenticated users should see this page</p> </div> </template>

使用您的Vue.js前端和身份验证流程进行测试 (Take Your Vue.js Frontend and Auth Flows for a Test Drive)

In your terminal run npm run dev (if it’s not already running). Navigate to http://localhost:8080 and you should see the new homepage.

在终端中运行npm run dev (如果尚未运行)。 导航到http://localhost:8080 ,您应该看到新的主页。

If you click Posts Manager or Login you should be directed to Okta’s flow. Enter your Okta dev account credentials.

如果您单击Posts Manager或Login ,则应转到Okta的流程。 输入您的Okta开发人员帐户凭据。

NOTE: If you are logged in to your Okta Developer Account you will be redirected automatically back to the app. You can test this by using incognito or private browsing mode.

注意:如果您登录到Okta开发者帐户,您将被自动重定向回该应用程序。 您可以使用隐身或私人浏览模式进行测试。

If successful, you should return to the homepage logged in.

如果成功,则应返回登录的主页。

Clicking on Posts Manager link should render the protected component.

单击Posts Manager链接应呈现受保护的组件。

添加后端REST API服务器 (Add a Backend REST API Server)

Now that users can securely authenticate, you can build the REST API server to perform CRUD operations on a post model. Add the following dependencies to your project:

现在,用户可以安全地进行身份验证,您可以构建REST API服务器以在帖子模型上执行CRUD操作。 将以下依赖项添加到您的项目中:

npm i --save express cors @okta/jwt-verifier sequelize sqlite3 epilogue axios

Then, create the file ./src/server.js and paste the following code.

然后,创建文件./src/server.js并粘贴以下代码。

const express = require('express') const cors = require('cors') const bodyParser = require('body-parser') const Sequelize = require('sequelize') const epilogue = require('epilogue') const OktaJwtVerifier = require('@okta/jwt-verifier') const oktaJwtVerifier = new OktaJwtVerifier({ clientId: '{yourClientId}', issuer: 'https://{yourOktaDomain}.com/oauth2/default' }) let app = express() app.use(cors()) app.use(bodyParser.json()) // verify JWT token middleware app.use((req, res, next) => { // require every request to have an authorization header if (!req.headers.authorization) { return next(new Error('Authorization header is required')) } let parts = req.headers.authorization.trim().split(' ') let accessToken = parts.pop() oktaJwtVerifier.verifyAccessToken(accessToken) .then(jwt => { req.user = { uid: jwt.claims.uid, email: jwt.claims.sub } next() }) .catch(next) // jwt did not verify! }) // For ease of this tutorial, we are going to use SQLite to limit dependencies let database = new Sequelize({ dialect: 'sqlite', storage: './test.sqlite' }) // Define our Post model // id, createdAt, and updatedAt are added by sequelize automatically let Post = database.define('posts', { title: Sequelize.STRING, body: Sequelize.TEXT }) // Initialize epilogue epilogue.initialize({ app: app, sequelize: database }) // Create the dynamic REST resource for our Post model let userResource = epilogue.resource({ model: Post, endpoints: ['/posts', '/posts/:id'] }) // Resets the database and launches the express app on :8081 database .sync({ force: true }) .then(() => { app.listen(8081, () => { console.log('listening to port localhost:8081') }) })

Make sure to replace the variables {yourOktaDomain} and {clientId} in the above code with values from your OIDC app in Okta.

确保使用来自Okta的OIDC应用中的值替换上面代码中的变量{yourOktaDomain}和{clientId} 。

添加续集 (Add Sequelize)

Sequelize is a promise-based ORM for Node.js. It supports the dialects PostgreSQL, MySQL, SQLite, and MSSQL and features solid transaction support, relations, read replication, and more.

Sequelize是Node.js的基于承诺的ORM。 它支持方言PostgreSQL,MySQL,SQLite和MSSQL,并具有可靠的事务支持,关系,读取复制等功能。

For ease of this tutorial, you’re going to use SQLite to limit external dependencies. The following code initializes a Sequelize instance using SQLite as your driver.

为了简化本教程,您将使用SQLite限制外部依赖关系。 以下代码使用SQLite作为驱动程序初始化Sequelize实例。

let database = new Sequelize({ dialect: 'sqlite', storage: './test.sqlite' })

Each post has a title and body. (The fields createdAt, and updatedAt are added by Sequelize automatically). With Sequelize, you define models by calling define() on your instance.

每个帖子都有title和body 。 (字段createdAt ,和updatedAt由Sequelize自动添加)。 使用Sequelize,您可以通过在实例上调用define()来定义模型。

let Post = database.define('posts', { title: Sequelize.STRING, body: Sequelize.TEXT })

添加结尾 (Add Epilogue)

Epilogue creates flexible REST endpoints from Sequelize models within an Express app. If you ever coded REST endpoints you know how much repetition there is. D.R.Y. FTW!

Epilogue通过Express应用程序中的Sequelize模型创建灵活的REST端点。 如果您曾经编码过REST端点,您就会知道有多少重复。 干FTW!

// Initialize epilogue epilogue.initialize({ app: app, sequelize: database }) // Create the dynamic REST resource for our Post model let userResource = epilogue.resource({ model: Post, endpoints: ['/posts', '/posts/:id'] })

验证您的JWT (Verify Your JWT)

This is the most crucial component of your REST API server. Without this middleware any user can perform CRUD operations on our database. If no authorization header is present, or the access token is invalid, the API call will fail and return an error.

这是REST API服务器最关键的组件。 没有此中间件,任何用户都可以在我们的数据库上执行CRUD操作。 如果不存在授权头,或者访问令牌无效,则API调用将失败并返回错误。

// verify JWT token middleware app.use((req, res, next) => { // require every request to have an authorization header if (!req.headers.authorization) { return next(new Error('Authorization header is required')) } let parts = req.headers.authorization.trim().split(' ') let accessToken = parts.pop() oktaJwtVerifier.verifyAccessToken(accessToken) .then(jwt => { req.user = { uid: jwt.claims.uid, email: jwt.claims.sub } next() }) .catch(next) // jwt did not verify! })

运行服务器 (Run the Server)

Open a new terminal window and run the server with the command node ./src/server. You should see debug information from Sequelize and the app listening on port 8081.

打开一个新的终端窗口,并使用命令node ./src/server运行服务器。 您应该从Sequelize中看到调试信息,并且该应用程序正在侦听端口8081。

完成帖子管理器组件 (Complete the Posts Manager Component)

Now that the REST API server is complete, you can start wiring up your posts manager to fetch posts, create posts, edit posts, and delete posts.

现在REST API服务器已经完成,您可以开始连接帖子管理器以获取帖子,创建帖子,编辑帖子和删除帖子。

I always centralize my API integrations into a single helper module. This keeps the code in components much cleaner and provides single location in case you need to change anything with the API request.

我总是将我的API集成集中到单个帮助程序模块中。 这样可以使组件中的代码更加整洁,并提供单个位置,以防您需要通过API请求进行任何更改。

Create a file ./src/api.js and copy/paste the following code into it:

创建一个文件./src/api.js并将以下代码复制/粘贴到其中:

import Vue from 'vue' import axios from 'axios' const client = axios.create({ baseURL: 'http://localhost:8081/', json: true }) export default { async execute (method, resource, data) { // inject the accessToken for each request let accessToken = await Vue.prototype.$auth.getAccessToken() return client({ method, url: resource, data, headers: { Authorization: `Bearer ${accessToken}` } }).then(req => { return req.data }) }, getPosts () { return this.execute('get', '/posts') }, getPost (id) { return this.execute('get', `/posts/${id}`) }, createPost (data) { return this.execute('post', '/posts', data) }, updatePost (id, data) { return this.execute('put', `/posts/${id}`, data) }, deletePost (id) { return this.execute('delete', `/posts/${id}`) } }

When you authenticate with OIDC, an access token is persisted locally in the browser. Since each API request must have an access token, you can fetch it from the authentication client and set it in the request.

当您使用OIDC进行身份验证时,访问令牌将在浏览器中本地保留。 由于每个API请求都必须具有访问令牌,因此您可以从身份验证客户端获取它,并将其设置在请求中。

let accessToken = await Vue.prototype.$auth.getAccessToken() return client({ method, url: resource, data, headers: { Authorization: `Bearer ${accessToken}` } })

By creating the following proxy methods inside your API helper, the code outside the helper module remains clean and semantic.

通过在API帮助器中创建以下代理方法,帮助器模块外部的代码将保持清晰和语义。

getPosts () { return this.execute('get', '/posts') }, getPost (id) { return this.execute('get', `/posts/${id}`) }, createPost (data) { return this.execute('post', '/posts', data) }, updatePost (id, data) { return this.execute('put', `/posts/${id}`, data) }, deletePost (id) { return this.execute('delete', `/posts/${id}`) }

You now have all the components required to wire up your posts manager component to make CRUD operations via the REST API. Open ./src/components/PostsManager.vue and copy/paste the following code.

现在,您具有连接帖子管理器组件以通过REST API进行CRUD操作所需的所有组件。 打开./src/components/PostsManager.vue并复制/粘贴以下代码。

<template> <div class="container-fluid mt-4"> <h1 class="h1">Posts Manager</h1> <b-alert :show="loading" variant="info">Loading...</b-alert> <b-row> <b-col> <table class="table table-striped"> <thead> <tr> <th>ID</th> <th>Title</th> <th>Updated At</th> <th>&nbsp;</th> </tr> </thead> <tbody> <tr v-for="post in posts" :key="post.id"> <td>{{ post.id }}</td> <td>{{ post.title }}</td> <td>{{ post.updatedAt }}</td> <td class="text-right"> <a href="#" @click.prevent="populatePostToEdit(post)">Edit</a> - <a href="#" @click.prevent="deletePost(post.id)">Delete</a> </td> </tr> </tbody> </table> </b-col> <b-col lg="3"> <b-card :title="(model.id ? 'Edit Post ID#' + model.id : 'New Post')"> <form @submit.prevent="savePost"> <b-form-group label="Title"> <b-form-input type="text" v-model="model.title"></b-form-input> </b-form-group> <b-form-group label="Body"> <b-form-textarea rows="4" v-model="model.body"></b-form-textarea> </b-form-group> <div> <b-btn type="submit" variant="success">Save Post</b-btn> </div> </form> </b-card> </b-col> </b-row> </div> </template> <script> import api from '@/api' export default { data () { return { loading: false, posts: [], model: {} } }, async created () { this.refreshPosts() }, methods: { async refreshPosts () { this.loading = true this.posts = await api.getPosts() this.loading = false }, async populatePostToEdit (post) { this.model = Object.assign({}, post) }, async savePost () { if (this.model.id) { await api.updatePost(this.model.id, this.model) } else { await api.createPost(this.model) } this.model = {} // reset form await this.refreshPosts() }, async deletePost (id) { if (confirm('Are you sure you want to delete this post?')) { // if we are editing a post we deleted, remove it from the form if (this.model.id === id) { this.model = {} } await api.deletePost(id) await this.refreshPosts() } } } } </script>

上市帖子 (Listing Posts)

You’ll use api.getPosts() to fetch posts from your REST API server. You should refresh the list of posts when the component is loaded and after any mutating operation (create, update, or delete).

您将使用api.getPosts()从REST API服务器中获取帖子。 加载组件时以及任何更改操作(创建,更新或删除)之后,您应该刷新帖子列表。

async refreshPosts () { this.loading = true this.posts = await api.getPosts() this.loading = false }

The attribute this.loading is toggled so the UI can reflect the pending API call. You might not see the loading message since the API request is not going out to the internet.

切换this.loading属性,以便UI可以反映未决的API调用。 您可能看不到加载消息,因为API请求没有发送到互联网。

创建帖子 (Creating Posts)

A form is included in the component to save a post. It’s wired up to call savePosts() when the form is submitted and its inputs are bound to the model object on the component.

组件中包含一个表格来保存帖子。 提交表单并将表单的输入绑定到组件上的model对象时,它会连接调用savePosts() 。

When savePost() is called, it will perform either an update or create based on the existence of model.id. This is mostly a shortcut to not have to define two separate forms for creating and updating.

调用savePost() ,它将基于model.id的存在执行更新或创建。 这通常是一种快捷方式,不必定义两个单独的表单即可进行创建和更新。

async savePost () { if (this.model.id) { await api.updatePost(this.model.id, this.model) } else { await api.createPost(this.model) } this.model = {} // reset form await this.refreshPosts() }

更新帖子 (Updating Posts)

When updating a post, you first must load the post into the form. This sets model.id which will the trigger an update in savePost().

更新帖子时,首先必须将帖子加载到表单中。 这将设置model.id ,它将触发savePost()的更新。

async populatePostToEdit (post) { this.model = Object.assign({}, post) }

Important: The Object.assign() call copies the value of the post argument rather than the reference. When dealing with mutation of objects in Vue, you should always set to the value, not reference.

重要提示: Object.assign()调用复制post参数而不是引用的值。 在Vue中处理对象变异时,应始终将其设置为值,而不是引用。

删除帖子 (Deleting Posts)

To delete a post simply call api.deletePost(id). It’s always good to confirm before delete so let’s throw in a native confirmation alert box to make sure the click was intentional.

要删除帖子,只需调用api.deletePost(id) 。 在删除之前进行确认始终是一件好事,因此让我们在本机确认警报框中添加以确保单击是有意的。

async deletePost (id) { if (confirm('Are you sure you want to delete this post?')) { await api.deletePost(id) await this.refreshPosts() } }

测试您的Vue.js + Node CRUD应用 (Test Your Vue.js + Node CRUD App)

Make sure both the server and frontend are running.

确保服务器和前端都在运行。

Terminal #1

1号航站楼

node ./src/server

Terminal #2

2号航站楼

npm run dev

Navigate to http://localhost:8080 and give it a whirl.

导航到http://localhost:8080并进行旋转。

用Vue做更多事! (Do More With Vue!)

As I said at the top of this post, I think Vue stands head and shoulders above other frameworks. Here are five quick reasons why:

正如我在这篇文章的开头所说,我认为Vue领先于其他框架。 以下是五个快速原因:

Simple component lifecycle

简单的组件生命周期

HTML-based templating and native two-way binding

基于HTML的模板和本机双向绑定

Widely agreed upon ways to handle routing, state management, webpack configuration, and isomorphic web apps

广泛同意处理路由 , 状态管理 , Webpack配置和同构Web应用程序的方法

Massive community supported resources, components, libraries, and projects

大量社区支持的资源,组件,库和项目

Vue feels very similar to React (without the JSX!) which lowers the barrier to entry for those with React experience. Moving between React and Vue isn’t very difficult.

Vue与React (没有JSX!)非常相似,它降低了具有React经验的人员的进入门槛。 在React和Vue之间移动不是很困难。

I covered a lot of material in this tutorial but don’t feel bad if you didn’t grasp everything the first time. The more you work with these technologies, the more familiar they will become.

我在本教程中介绍了很多内容,但是如果您第一次不掌握所有内容,也不会感到难过。 您使用这些技术的次数越多,他们就会变得越熟悉。

To learn more about Vue.js head over to https://vuejs.org or check out these other great resources from the @oktadev team:

要了解有关Vue.js的更多信息,请转到https://vuejs.org或从@oktadev团队中查看以下其他重要资源:

The Ultimate Guide to Progressive Web Applications

渐进式Web应用程序终极指南

The Lazy Developer’s Guide to Authentication with Vue.js

懒惰的Vue.js开发人员认证指南

Build a Cryptocurrency Comparison Site with Vue.js

使用Vue.js构建一个加密货币比较网站

You can find the source code for the application developed in this post at https://github.com/oktadeveloper/okta-vue-node-example.

您可以在https://github.com/oktadeveloper/okta-vue-node-example上找到本文中开发的应用程序的源代码。

As always, follow @oktadev on Twitter to see all the cool content our dev team is creating.

与往常一样,在Twitter上关注@oktadev ,以查看我们的开发团队正在创建的所有精彩内容。

翻译自: https://www.sitepoint.com/add-authentication-vue-okta/

okta使用

相关资源:okta-auth-js, 用于 Okta API身份验证的正式js包装器.zip
最新回复(0)