├── .babelrc ├── .gitignore ├── .postcssrc ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html └── src ├── App.vue ├── assets └── logo.png ├── auth.js ├── components └── HelloWorld.vue ├── main.js ├── router.js └── views ├── Callback.vue └── Home.vue /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "@vue/app" 4 | ] 5 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | -------------------------------------------------------------------------------- /.postcssrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": { 3 | "autoprefixer": {} 4 | } 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Auth0 Vue 2 | 3 | Make sure to exchnage the auth0 information with your own in the `auth.js`. 4 | 5 | ## A Vue.js Demo Application which uses Auth0 for Authentication 6 | 7 | ![Final Result](https://img.storyblok.com/8hXRKaQfX1jUBSk8jcul2xZdBZM=/957x0/f/39898/2466x1760/dab8c6f648/final-result.png) 8 | 9 | You can follow the full tutorial on [Storyblok](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication) or simply use this as a boilerplate for your applications. 10 | 11 | ## The tutorial for this repository... 12 | 13 | can be found on [Storyblok](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication). It guides you through the following steps: 14 | 15 | - [Introduction](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication) 16 | - [Environment Setup](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#environment-setup) 17 | - [Prepare Auth0](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#prepare-auth0) 18 | - [Auth0 Callback Route](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#auth0-callback-route) 19 | - [Auth0 + Vue.js Authentication](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#setup-auth0--vuejs-auth-plugin) 20 | - [Adding a Navigation Guard](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#adding-a-navigation-guard) 21 | - [Accessing User Information](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication#accessing-user-information) 22 | 23 | ## How to use 24 | 25 | 1. Checkout this repository 26 | 2. Exchange your Auth0 client settings in `src/auth.js` 27 | 3. Navigate into the project folder 28 | 4. Execute `npm install` or `yarn` to install dependencies 29 | 5. Start application: `npm run serve` 30 | 31 | ## Feedback 32 | 33 | I'm looking forward to receive your feedback, best place would definitly be in the comment section at the bottom of the [tutorial on Storyblok](https://www.storyblok.com/tp/how-to-auth0-vuejs-authentication). 34 | 35 | ## What to expect 36 | 37 | This application/tutorial gives you a quick feeling of how to use Auth0 with your Vue.js application, you can also use it as a starting point for your projects. 38 | 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auth0-vue", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --open", 7 | "build": "vue-cli-service build" 8 | }, 9 | "dependencies": { 10 | "auth0-js": "^9.3.0", 11 | "axios": "^0.17.1", 12 | "vue": "^2.5.16", 13 | "vue-router": "^3.0.1" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.0.0-beta.11", 17 | "@vue/cli-service": "^3.0.0-beta.11", 18 | "vue-template-compiler": "^2.5.16" 19 | }, 20 | "browserslist": [ 21 | "> 1%", 22 | "last 2 versions", 23 | "not ie <= 8" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DominikAngerer/auth0-vue/2081aa631a36e36c947c5b653ae8ad2ee1f098c7/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | my-project 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DominikAngerer/auth0-vue/2081aa631a36e36c947c5b653ae8ad2ee1f098c7/src/assets/logo.png -------------------------------------------------------------------------------- /src/auth.js: -------------------------------------------------------------------------------- 1 | import auth0 from 'auth0-js' 2 | import Vue from 'vue' 3 | 4 | // exchange the object with your own from the setup step above. 5 | let webAuth = new auth0.WebAuth({ 6 | domain: 'YOUR_AUTH0_DOMAIN_HERE', 7 | clientID: 'YOUR_CLIENT_SECRET_HERE', 8 | // make sure port is 8080 9 | redirectUri: 'http://localhost:8080/callback', 10 | // we will use the api/v2/ to access the user information as payload 11 | audience: 'https://YOUR_AUTH0_DOMAIN_HERE/api/v2/', 12 | responseType: 'token id_token', 13 | scope: 'openid profile' 14 | }) 15 | 16 | let auth = new Vue({ 17 | computed: { 18 | token: { 19 | get: function() { 20 | return localStorage.getItem('id_token') 21 | }, 22 | set: function(id_token) { 23 | localStorage.setItem('id_token', id_token) 24 | } 25 | }, 26 | accessToken: { 27 | get: function() { 28 | return localStorage.getItem('access_token') 29 | }, 30 | set: function(accessToken) { 31 | localStorage.setItem('access_token', accessToken) 32 | } 33 | }, 34 | expiresAt: { 35 | get: function() { 36 | return localStorage.getItem('expires_at') 37 | }, 38 | set: function(expiresIn) { 39 | let expiresAt = JSON.stringify(expiresIn * 1000 + new Date().getTime()) 40 | localStorage.setItem('expires_at', expiresAt) 41 | } 42 | }, 43 | user: { 44 | get: function() { 45 | return JSON.parse(localStorage.getItem('user')) 46 | }, 47 | set: function(user) { 48 | localStorage.setItem('user', JSON.stringify(user)) 49 | } 50 | } 51 | }, 52 | methods: { 53 | login() { 54 | webAuth.authorize() 55 | }, 56 | logout() { 57 | return new Promise((resolve, reject) => { 58 | localStorage.removeItem('access_token') 59 | localStorage.removeItem('id_token') 60 | localStorage.removeItem('expires_at') 61 | localStorage.removeItem('user') 62 | webAuth.logout({ 63 | returnTo: 'http://SOMEWHERE.ELSE.com', // Allowed logout URL listed in dashboard 64 | clientID: 'YOUR_CLIENT_ID_HERE', // Your client ID 65 | }) 66 | }) 67 | }, 68 | isAuthenticated() { 69 | return new Date().getTime() < this.expiresAt 70 | }, 71 | handleAuthentication() { 72 | return new Promise((resolve, reject) => { 73 | webAuth.parseHash((err, authResult) => { 74 | 75 | if (authResult && authResult.accessToken && authResult.idToken) { 76 | this.expiresAt = authResult.expiresIn 77 | this.accessToken = authResult.accessToken 78 | this.token = authResult.idToken 79 | this.user = authResult.idTokenPayload 80 | resolve() 81 | 82 | } else if (err) { 83 | this.logout() 84 | reject(err) 85 | } 86 | 87 | }) 88 | }) 89 | } 90 | } 91 | }) 92 | 93 | export default { 94 | install: function(Vue) { 95 | Vue.prototype.$auth = auth 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 31 | 32 | 33 | 49 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from '@/App.vue' 3 | import router from '@/router' 4 | 5 | import auth from '@/auth' 6 | 7 | Vue.use(auth) 8 | 9 | Vue.config.productionTip = false 10 | 11 | new Vue({ 12 | router, 13 | render: h => h(App) 14 | }).$mount('#app') 15 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Home from '@/views/Home.vue' 4 | import Callback from '@/views/Callback.vue' 5 | 6 | Vue.use(Router) 7 | 8 | const router = new Router({ 9 | mode: 'history', 10 | routes: [ 11 | { 12 | path: '/', 13 | name: 'home', 14 | component: Home 15 | }, 16 | { 17 | path: '/callback', 18 | name: 'callback', 19 | component: Callback 20 | } 21 | ] 22 | }) 23 | 24 | // very basic "setup" of a global guard 25 | router.beforeEach((to, from, next) => { 26 | if(to.name == 'callback') { // check if "to"-route is "callback" and allow access 27 | next() 28 | } else if (router.app.$auth.isAuthenticated()) { // if authenticated allow access 29 | next() 30 | } else { // trigger auth0's login. 31 | router.app.$auth.login() 32 | } 33 | }) 34 | 35 | export default router -------------------------------------------------------------------------------- /src/views/Callback.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 15 | 16 | 46 | -------------------------------------------------------------------------------- /src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 67 | 68 | 80 | --------------------------------------------------------------------------------