Custom Social Auth flow with auth.nuxtjs.org

Dinushanka
ITNEXT
Published in
4 min readMay 25, 2018

--

source

The nuxt-auth module works great with local and social media logins but things get messay when you try to exchange social login tokens with your local API token. The nuxt auth module doesn’t support custom auth flows with social logins. Actually, what nuxt-auth does is, it logs you in with a social network but it doesn’t allow you to exchange the social token with your own token. Therefore I’ve created this tutorial to make things easy for you.

So here’s how to keep it clean. First, clone the base app from my github. This is from my previous tutorial on nuxt-auth module. Check my ealier article on nuxt-auth for a detailed walk through on the downloaded project.

I have used epic-spinners for loading animations. You can install epic spinners using the following command.

npm install --save epic-spinners

Then create a plugin called spinners.js in the plugins folder to include epic spinners into your project.

import Vue from 'vue'
import { SemipolarSpinner } from 'epic-spinners'
Vue.component('semipolar-spinner', SemipolarSpinner)

Then include the plugin into nuxt.config.js

plugins: ['~plugins/spinners.js'],

Let’s get Started with the auth flow

Here’s what we are going to do. First we’ll let nuxt-auth plugin, login with a social network. Then we’ll obtain the token received with the callback from facebook, google or any other platform. Then we’ll send that token to our own server and exchange the social login token with a local token. Then we’ll forcefully set the local authtoken in nuxt-auth module. After doing so, we’ll have to change the strategy to local and finally you can fetch the local user from your own API. To make things clean, we’ll create a plugin for axios and include all the headers in the axios plugin. Then we’ll include the plugin ino the project.

First

You should change the nuxt.auth config to suite your auth flow. Here’s how I did it.

auth: {
strategies: {
local: {
endpoints: {
login: {url: '/user/login', method: 'post', propertyName: 'token' },
logout: false,
user: {url: '/user/user', method: 'get', propertyName: 'data'},
},
tokenRequired: true,
tokenType: 'Bearer'
},
facebook: {
client_id: '',
userinfo_endpoint: false,
scope: ['public_profile', 'email'],
redirect_uri:'http://localhost:3000/callback'
},
google: {
client_id: '',
user:false,
redirect_uri:'http://localhost:3000/callback'

},
},
redirect: {
login: '/?login=1',
logout: '/',
}
},

Then add your API endpoint to work as the base

axios: {
baseURL:'https://aaa.com/api/v1'
},

I have purposefully removed the rest of the configuration. Refer the given github for complete configuration.

Second

Let’s setup axios. Here, i’ll create a plugin to keep all the headers in one place. To get started, create a file named axios.js in plugins and include it in the nuxt.config.js Here’s a look of the minimal nuxt config after including the relevent plugins.

plugins: [‘~plugins/axios.js’,’~plugins/spinners.js’]

Then put the following code into the axios.js in plugins folder.

export default function ({$axios, redirect}) {
$axios.onRequest(config => {
config.headers['Content-Type'] = 'application/json';
config.headers['Access-Control-Allow-Origin'] = "*";
})
}

If you need more headers, just include them in the axios plugin and axios will automatically inject the headers when sending a request.

Now that we have setup axios. Let’s create the custom auth plugin. Create a new file called auth.js in the plugins folder and type the following code.

export default async function ({ app }) {
if (!app.$auth.loggedIn) {
return
}
const auth = app.$auth;const authStrategy = auth.strategy.name;
if(authStrategy === 'facebook' || authStrategy === 'google'){
const token = auth.getToken(authStrategy).substr(7)
const authStrategyConverted = authStrategy === 'facebook' ? 'fb' : 'google';
const url = `/user/signup/${authStrategyConverted}?token=${token}`;
try {
const {data} = await app.$axios.$post(url, null);
auth.setToken('local', "Bearer "+ data.access_token);
setTimeout( async () => {
auth.setStrategy('local');
setTimeout( async () => {
await auth.fetchUser();
})
});
} catch (e) {
console.log(e);
}
}
}

As you know, the nuxt-auth module keeps the login state in $auth.loggedIn variable. Therefore, at first we have to check whether the user is already logged in. If not logged in, this method should exit. Remember what I told you earlier, We should let the nuxt-auth module login before we intervene. Then we’ll copy the logged status to a variable so that we don’t have to repeat $nuxt.auth around the code.

Then i’m accessing the strategy. This is important since we are customizing the social media auth flow. You can access the currently logged strategy from nuxt-auth via auth.strategy.name (app.$auth.strategy.name). We are doing this, only to allow social logins. Then get the saved social login access token from nuxt-auth via auth.getToken(authStrategy).substr(7). Here auth.getToken(‘strategy name’) is a default method built into nuxt-auth. Refer the documentation for more information.

const authStrategyConverted = authStrategy === 'facebook' ? 'fb' : 'google';
const url = `/user/signup/${authStrategyConverted}?token=${token}`;

Using the above code, I’m creating the url based on the strategy. Then send a post call to your endpoint to retrive a custom token and set the local token to Vuex via auth.setToken(‘strategy’, token) method. Your API must get the social token, retrive the relevent user information and issue a access token.
The strategy should be local here. Then change the strategy to local using auth.setStrategy(‘ strategy ‘) method.

Finally include this plugin to nuxtjs globally.

plugins: ['~plugins/auth.js','~plugins/axios.js','~plugins/spinners.js']

Here is the github link of the repo. This is the end of this tutorial ❤

GITHUB REPO

git clone https://github.com/rama41222/NuxtMedium.git

--

--