Authentication is a crucial aspect of any modern web application. Whether you’re building an e-commerce site, a social platform, or any service requiring user authentication, handling authentication securely and efficiently is key to ensuring a smooth user experience. In this post, we’ll explore how to easily integrate authentication into your Nuxt.js application using the @workmate/nuxt-auth package. We would discuss the local auth provider here, where you can connect to your backend directly. The package also has support for oAuth2 like github and google. To view that, check out the github repository
https://github.com/work-mate/nuxt-auth-module
What is @workmate/nuxt-auth?
@workmate/nuxt-auth is a package designed to make authentication in Nuxt.js apps seamless. This package provides a straightforward way to add authentication flows, such as login, registration, and user session management, to your Nuxt app.
Installing @workmate/nuxt-auth
The first step is to install the package. Open your terminal and navigate to the root of your Nuxt project. Then, run the following command to install the @workmate/nuxt-auth package:
npm install --save @workmate/nuxt-auth
or if you are using yarn:
yarn add @workmate/nuxt-auth
Setting Up the Package in Your Nuxt Project
Once the package is installed, you need to configure it in your Nuxt application. Open your nuxt.config.js file and add @workmate/nuxt-auth to the modules array:
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
"@workmate/nuxt-auth"
],
...
});
Set up your auth providers
// nuxt.config.ts
const BACKEND_URL = process.env.BACKEND_BASE_URL || "http://localhost:9000";
export default defineNuxtConfig({
modules: [ "@workmate/nuxt-auth",],
auth: {
global: true,
redirects: {
redirectIfLoggedIn: "/dashboard",
redirectIfNotLoggedIn: "/register", // default is /login
},
apiClient: {
baseURL: BACKEND_URL,
},
//token: {
// type: "Bearer",
// maxAge: 1000 * 60 * 60 * 24 * 30,
// cookiesNames: {
// accessToken: "auth:token",
// refreshToken: "auth:refreshToken",
// authProvider: "auth:provider",
// tokenType: "auth:tokenType",
//}
};
providers: {
local: {
endpoints: {
signIn: {
path: `${BACKEND_URL}/api/auth/login`,
method: "POST",
tokenKey: "token",
body: {
principal: "email",
password: "password",
},
},
user: {
path: `${BACKEND_URL}/api/auth/user`,
userKey: "data",
},
signOut: {
path: `${BACKEND_URL}/api/auth/user`,
method: "POST",
},
},
},
},
},
});
Brief explanation of the config
Let's go through the above real quick, the global:true
line ensures that the auth middleware is set on every page of your website. And since you won't be authenticated by default, you want to turn it off on the home route like so
// pages/index.vue
<template>
<main>Landing page</main>
</template>
<script lang="ts" setup>
definePageMeta({
auth: false,
});
<script>
You can also set the auth to false on pages you want your users to access regardless of whether they are logged in or not like the help page or the about us page.
In the case where you don't want to use the global middleware, add the auth middleware to the pages you want to protect, eg the dashboard
// pages/dashboard.vue
<template>
<main>Dashboard page</main>
</template>
<script lang="ts" setup>
definePageMeta({
middleware: "auth",
});
<script>
The signIn endpoint
In the above config, the application would make a post request to the endpoint ${BACKEND_URL}/api/auth/login
with the body
{
"email": "email@example.com",
"password": "password"
}
and would expect data with the format
{
"token": "auth token",
}
for nested data, use 'period' separated keys eg nested.token.data
.
The same foes for the user endpoint and the sign out endpoint.
The api client
By default, nuxt would want you to send requests to your frontend domain, meanwhile you might want to send it to another (eg. the backend). This package automatically handles this and also adds the authorization headers to the api client so you don't have to manually do that.
To use the api client, add the apiClient's baseurl to the config as shown in the code above. Then instead of calling useFetch or $fetch in nuxt use
useAuthFetch(url, options)
const { $authFetch } = useNuxtApp();
$authFetch(url, options)
And they have the exact same interface with the useFetch and $fetch apis.
Logging In
// pages/index.vue
<template>
<form @submit.prevent="submit" class="login-form">
<div class="form-group">
<label for="email">Email</label>
<input
type="email"
id="email"
v-model="email"
placeholder="Enter your email"
required
/>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
type="password"
id="password"
v-model="password"
placeholder="Enter your password"
required
/>
</div>
<button type="submit">Login</button>
</form>
</template>
<script lang="ts" setup>
definePageMeta({
middleware: 'auth-guest',
});
const email = ref();
const password = ref();
const { login } = useAuth();
function submit() {
login("local", {
principal: email.value,
password: password.value,
}).catch(err => {
//handle error
})
}
<script>
The auth guest middleware allows only unauthenticated users to visit a page, which is what we need in the case of the login.
Auth Data
In order to get the auth data, you can use the useAuth composable
const {
loggedIn,
user,
token,
refreshToken,
login,
logout,
refreshUser,
refreshTokens,
} = useAuth();
// or
const { $auth } = useNuxtApp();
const {
loggedIn,
user,
token,
refreshToken,
login,
logout,
refreshUser,
refreshTokens,
} = $auth;
In order to logout, you can use the logout from the above code snippet
logout().then(() => {
// show logout notification
});
Top comments (0)