├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── components └── Loading.vue ├── layouts └── default.vue ├── middleware └── README.md ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages ├── callback.vue └── index.vue ├── plugins ├── auth.js ├── axios.js ├── spinners.js └── vee.js ├── static └── favicon.ico └── store ├── README.md └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention 12 | // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. 13 | 'plugin:vue/essential' 14 | ], 15 | // required to lint *.vue files 16 | plugins: [ 17 | 'vue' 18 | ], 19 | // add your custom rules here 20 | rules: {} 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | # logs 5 | npm-debug.log 6 | 7 | # Nuxt build 8 | .nuxt 9 | 10 | # Nuxt generate 11 | dist 12 | 13 | .idea 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NUXT Custom Social Login 2 | 3 | ##### Pre Configuration 4 | 5 | Add the google oAuth client ID, Facebook app client ID and the API base url first 6 | 7 | ##### Install the Dependencies 8 | ```` 9 | npm install 10 | ```` 11 | 12 | ##### update the Dependencies 13 | ```` 14 | npm update 15 | ```` 16 | 17 | ##### Run the project in dev mode 18 | ```` 19 | npm run dev 20 | ```` 21 | 22 | ##### Run the project in production mode 23 | ```` 24 | npm run start 25 | ```` 26 | 27 | * Port = 3000 28 | * Host = 0.0.0.0 29 | 30 | Read the full [@medium](https://medium.com/@rama41222/custom-social-auth-flow-with-auth-nuxtjs-org-daa836676587) 31 | post. 32 | -------------------------------------------------------------------------------- /components/Loading.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 28 | 29 | 50 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 53 | -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | This directory contains your Application Middleware. 4 | The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts). 5 | 6 | More information about the usage of this directory in the documentation: 7 | https://nuxtjs.org/guide/routing#middleware 8 | 9 | **This directory is not required, you can delete it if you don't want to use it.** 10 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | head: { 3 | title: 'Auth Test', 4 | meta: [ 5 | {charset: 'utf-8'}, 6 | {name: 'viewport', content: 'width=device-width, initial-scale=1'}, 7 | {hid: 'description', name: 'description', content: 'sd frontend application'} 8 | ], 9 | link: [ 10 | {rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}, 11 | {rel: 'stylesheet', href: 'https://cdn.linearicons.com/free/1.0.0/icon-font.min.css'}, 12 | {rel: 'stylesheet', href: 'https://use.fontawesome.com/releases/v5.0.8/css/all.css'}, 13 | {rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=IBM+Plex+Serif:300,400,500,600'}, 14 | {rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=GFS+Didot|Lato:100,300,400,700,900'}, 15 | {rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons'} 16 | ] 17 | }, 18 | modules: [ 19 | '@nuxtjs/axios', 20 | '@nuxtjs/auth', 21 | '@nuxtjs/toast', 22 | 'bootstrap-vue/nuxt' 23 | ], 24 | toast: { 25 | position: 'top-right', 26 | duration: 2000 27 | }, 28 | auth: { 29 | strategies: { 30 | local: { 31 | endpoints: { 32 | login: {url: '/user/login', method: 'post', propertyName: 'token' }, 33 | logout: false, 34 | user: {url: '/user/user', method: 'get', propertyName: 'data'}, 35 | }, 36 | tokenRequired: true, 37 | tokenType: 'Bearer' 38 | }, 39 | facebook: { 40 | client_id: '', 41 | userinfo_endpoint: false, 42 | scope: ['public_profile', 'email'], 43 | redirect_uri:'http://localhost:3000/callback' 44 | }, 45 | google: { 46 | client_id: '', 47 | user:false, 48 | redirect_uri:'http://localhost:3000/callback' 49 | 50 | }, 51 | }, 52 | redirect: { 53 | login: '/?login=1', 54 | logout: '/', 55 | } 56 | }, 57 | axios: { 58 | baseURL:'api base url' 59 | }, 60 | plugins: ['~plugins/vee.js',{ src:'~plugins/spinners.js', ssr: false },{ src:'~plugins/auth.js', ssr: false },'~plugins/axios.js'], 61 | loading: '~/components/Loading.vue', 62 | build: { 63 | vendor: ['vee-validate'], 64 | extend (config, { isDev, isClient }) { 65 | if (isDev && isClient) { 66 | config.module.rules.push({ 67 | enforce: 'pre', 68 | test: /\.(js|vue)$/, 69 | loader: 'eslint-loader', 70 | exclude: /(node_modules)/ 71 | }) 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "imi_pr", 3 | "version": "1.0.0", 4 | "description": "Nuxt.js project", 5 | "author": "rama41222 ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore .", 13 | "precommit": "npm run lint" 14 | }, 15 | "config": { 16 | "nuxt": { 17 | "host": "0.0.0.0", 18 | "port": "3000" 19 | } 20 | }, 21 | "dependencies": { 22 | "@nuxtjs/auth": "^4.5.1", 23 | "@nuxtjs/axios": "^5.3.1", 24 | "@nuxtjs/toast": "^3.0.1", 25 | "bootstrap-vue": "^2.0.0-rc.11", 26 | "epic-spinners": "^1.0.3", 27 | "nuxt": "^1.0.0", 28 | "vee-validate": "^2.0.9" 29 | }, 30 | "devDependencies": { 31 | "babel-eslint": "^8.2.1", 32 | "eslint": "^4.15.0", 33 | "eslint-friendly-formatter": "^3.0.0", 34 | "eslint-loader": "^1.7.1", 35 | "eslint-plugin-vue": "^4.0.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /pages/callback.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 49 | 50 | 59 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 106 | 107 | 128 | -------------------------------------------------------------------------------- /plugins/auth.js: -------------------------------------------------------------------------------- 1 | export default async function ({ app }) { 2 | console.log('auth executed') 3 | if (!app.$auth.loggedIn) { 4 | return 5 | } 6 | 7 | const auth = app.$auth; 8 | 9 | const authStrategy = auth.strategy.name; 10 | if(authStrategy === 'facebook' || authStrategy === 'google'){ 11 | const token = auth.getToken(authStrategy).substr(7); 12 | const authStrategyConverted = authStrategy === 'facebook' ? 'fb' : 'google'; 13 | const url = `/user/signup/${authStrategyConverted}?token=${token}`; 14 | 15 | try { 16 | const {data} = await app.$axios.$post(url, null); 17 | auth.setToken('local', "Bearer "+ data.access_token); 18 | setTimeout( async () => { 19 | auth.setStrategy('local'); 20 | setTimeout( async () => { 21 | await auth.fetchUser(); 22 | }) 23 | }); 24 | } catch (e) { 25 | console.log(e); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /plugins/axios.js: -------------------------------------------------------------------------------- 1 | export default function ({$axios, redirect}) { 2 | $axios.onRequest(config => { 3 | config.headers['Content-Type'] = 'application/json'; 4 | config.headers['Access-Control-Allow-Origin'] = "*"; 5 | }) 6 | } 7 | -------------------------------------------------------------------------------- /plugins/spinners.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import { FulfillingBouncingCircleSpinner } from 'epic-spinners' 3 | 4 | Vue.component('fulfilling-bouncing-circle-spinner', FulfillingBouncingCircleSpinner); 5 | -------------------------------------------------------------------------------- /plugins/vee.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VeeValidate from 'vee-validate'; 3 | 4 | Vue.use(VeeValidate); 5 | 6 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rama41222/NuxtMedium/37db4e1694aa63aa25605ec089881f23c95284da/static/favicon.ico -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | This directory contains your Vuex Store files. 4 | Vuex Store option is implemented in the Nuxt.js framework. 5 | Creating a index.js file in this directory activate the option in the framework automatically. 6 | 7 | More information about the usage of this directory in the documentation: 8 | https://nuxtjs.org/guide/vuex-store 9 | 10 | **This directory is not required, you can delete it if you don't want to use it.** 11 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rama41222/NuxtMedium/37db4e1694aa63aa25605ec089881f23c95284da/store/index.js --------------------------------------------------------------------------------