Build a Basic CRUD App with Vue.js and Node

2018-04-13 07:08 AM

912

Build a Basic CRUD App with Vue.js and Node

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

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.

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:

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.

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.

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.

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.

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.

About Vue.js

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).

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:

npm i --save @okta/okta-vue

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

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.

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.

You also need to lock down protected routes from being access 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.

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

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

meta: {
requiresAuth: true
}

About Vue.js

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.

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

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.

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.

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).

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.

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

About Vue.js

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.

About Vue.js

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.

About Vue.js

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.

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.

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.