Repository: bezkoder/vue-3-authentication-jwt Branch: master Commit: ca3b629b0559 Files: 22 Total size: 23.0 KB Directory structure: gitextract__tosskch/ ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── public/ │ └── index.html ├── src/ │ ├── App.vue │ ├── components/ │ │ ├── BoardAdmin.vue │ │ ├── BoardModerator.vue │ │ ├── BoardUser.vue │ │ ├── Home.vue │ │ ├── Login.vue │ │ ├── Profile.vue │ │ └── Register.vue │ ├── main.js │ ├── plugins/ │ │ └── font-awesome.js │ ├── router.js │ ├── services/ │ │ ├── auth-header.js │ │ ├── auth.service.js │ │ └── user.service.js │ └── store/ │ ├── auth.module.js │ └── index.js └── vue.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store node_modules /dist # local env files .env.local .env.*.local # Log files npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: README.md ================================================ # Vue 3 Authentication with JWT, Vuex and Vue Router ## Flow for User Registration and User Login ![vue-3-authentication-jwt-example-flow](vue-3-authentication-jwt-example-flow.png) - Signup Page: ![vue-3-authentication-jwt-example-vuex-user-registration](vue-3-authentication-jwt-example-vuex-user-registration.png) - Form Validation could look like this: ![vue-3-authentication-jwt-example-vuex-form-validation](vue-3-authentication-jwt-example-vuex-form-validation.png) - Login Page & Profile Page (for successful Login): ![vue-3-authentication-jwt-example-vuex-user-login](vue-3-authentication-jwt-example-vuex-user-login.png) For instruction, please visit: > [Vue 3 Authentication & Authorization with JWT, Vuex and Vue Router](https://bezkoder.com/vue-3-authentication-jwt/) ## Note: Open `src/services/auth-header.js` and modify `return` statement for appropriate back-end. ```js export default function authHeader() { let user = JSON.parse(localStorage.getItem('user')); if (user && user.accessToken) { return { Authorization: 'Bearer ' + user.accessToken }; // for Spring Boot back-end // return { 'x-access-token': user.accessToken }; // for Node.js Express back-end } else { return {}; } } ``` Related Posts: > [Vue 2 JWT Authentication with Vuex and Vue Router](https://bezkoder.com/jwt-vue-vuex-authentication/) > [Using Typescript](https://bezkoder.com/vuex-typescript-jwt-auth/) > [Vue 3 CRUD example with Axios and Vue Router](https://bezkoder.com/vue-3-crud/) Fullstack with Spring Boot Back-end: > [Spring Boot + Vue.js: Authentication with JWT & Spring Security Example](https://bezkoder.com/spring-boot-vue-js-authentication-jwt-spring-security/) Fullstack with Node.js Express Back-end: > [Node.js Express + Vue.js: JWT Authentication & Authorization example](https://bezkoder.com/node-express-vue-jwt-auth/) Fullstack CRUD: > [Vue.js + Node.js + Express + MySQL example](https://bezkoder.com/vue-js-node-js-express-mysql-crud-example/) > [Vue.js + Node.js + Express + PostgreSQL example](https://bezkoder.com/vue-node-express-postgresql/) > [Vue.js + Node.js + Express + MongoDB example](https://bezkoder.com/vue-node-express-mongodb-mevn-crud/) > [Vue.js + Spring Boot + MySQL/PostgreSQL example](https://bezkoder.com/spring-boot-vue-js-crud-example/) > [Vue.js + Spring Boot + MongoDB example](https://bezkoder.com/spring-boot-vue-mongodb/) > [Vue.js + Django example](https://bezkoder.com/django-vue-js-rest-framework/) Integration (run on same server/port): > [Integrate Vue.js with Spring Boot](https://bezkoder.com/integrate-vue-spring-boot/) > [Integrate Vue App with Node.js Express](https://bezkoder.com/serve-vue-app-express/) ## Project setup ``` npm install ``` ### Compiles and hot-reloads for development ``` npm run serve ``` ### Compiles and minifies for production ``` npm run build ``` ### Lints and fixes files ``` npm run lint ``` ### Customize configuration See [Configuration Reference](https://cli.vuejs.org/config/). ================================================ FILE: babel.config.js ================================================ module.exports = { presets: [ '@vue/cli-plugin-babel/preset' ] } ================================================ FILE: package.json ================================================ { "name": "vue-3-authentication-jwt", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/vue-fontawesome": "^3.0.0-3", "axios": "^0.21.1", "bootstrap": "^4.6.0", "core-js": "^3.6.5", "jquery": "^3.6.0", "popper.js": "^1.16.1", "vee-validate": "^4.3.5", "vue": "^3.0.0", "vue-router": "^4.0.6", "vuex": "^4.0.0", "yup": "^0.32.9" }, "devDependencies": { "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-service": "~4.5.0", "@vue/compiler-sfc": "^3.0.0", "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^7.0.0" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/vue3-essential", "eslint:recommended" ], "parserOptions": { "parser": "babel-eslint" }, "rules": {} }, "browserslist": [ "> 1%", "last 2 versions", "not dead" ] } ================================================ FILE: public/index.html ================================================ <%= htmlWebpackPlugin.options.title %>
================================================ FILE: src/App.vue ================================================ ================================================ FILE: src/components/BoardAdmin.vue ================================================ ================================================ FILE: src/components/BoardModerator.vue ================================================ ================================================ FILE: src/components/BoardUser.vue ================================================ ================================================ FILE: src/components/Home.vue ================================================ ================================================ FILE: src/components/Login.vue ================================================ ================================================ FILE: src/components/Profile.vue ================================================ ================================================ FILE: src/components/Register.vue ================================================ ================================================ FILE: src/main.js ================================================ import { createApp } from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; import "bootstrap"; import "bootstrap/dist/css/bootstrap.min.css"; import { FontAwesomeIcon } from './plugins/font-awesome' createApp(App) .use(router) .use(store) .component("font-awesome-icon", FontAwesomeIcon) .mount("#app"); ================================================ FILE: src/plugins/font-awesome.js ================================================ import { library } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { faHome, faUser, faUserPlus, faSignInAlt, faSignOutAlt, } from "@fortawesome/free-solid-svg-icons"; library.add(faHome, faUser, faUserPlus, faSignInAlt, faSignOutAlt); export { FontAwesomeIcon }; ================================================ FILE: src/router.js ================================================ import { createWebHistory, createRouter } from "vue-router"; import Home from "./components/Home.vue"; import Login from "./components/Login.vue"; import Register from "./components/Register.vue"; // lazy-loaded const Profile = () => import("./components/Profile.vue") const BoardAdmin = () => import("./components/BoardAdmin.vue") const BoardModerator = () => import("./components/BoardModerator.vue") const BoardUser = () => import("./components/BoardUser.vue") const routes = [ { path: "/", name: "home", component: Home, }, { path: "/home", component: Home, }, { path: "/login", component: Login, }, { path: "/register", component: Register, }, { path: "/profile", name: "profile", // lazy-loaded component: Profile, }, { path: "/admin", name: "admin", // lazy-loaded component: BoardAdmin, }, { path: "/mod", name: "moderator", // lazy-loaded component: BoardModerator, }, { path: "/user", name: "user", // lazy-loaded component: BoardUser, }, ]; const router = createRouter({ history: createWebHistory(), routes, }); // router.beforeEach((to, from, next) => { // const publicPages = ['/login', '/register', '/home']; // const authRequired = !publicPages.includes(to.path); // const loggedIn = localStorage.getItem('user'); // // trying to access a restricted page + not logged in // // redirect to login page // if (authRequired && !loggedIn) { // next('/login'); // } else { // next(); // } // }); export default router; ================================================ FILE: src/services/auth-header.js ================================================ export default function authHeader() { let user = JSON.parse(localStorage.getItem('user')); if (user && user.accessToken) { return { Authorization: 'Bearer ' + user.accessToken }; // for Spring Boot back-end // return { 'x-access-token': user.accessToken }; // for Node.js Express back-end } else { return {}; } } ================================================ FILE: src/services/auth.service.js ================================================ import axios from 'axios'; const API_URL = 'http://localhost:8080/api/auth/'; class AuthService { login(user) { return axios .post(API_URL + 'signin', { username: user.username, password: user.password }) .then(response => { if (response.data.accessToken) { localStorage.setItem('user', JSON.stringify(response.data)); } return response.data; }); } logout() { localStorage.removeItem('user'); } register(user) { return axios.post(API_URL + 'signup', { username: user.username, email: user.email, password: user.password }); } } export default new AuthService(); ================================================ FILE: src/services/user.service.js ================================================ import axios from 'axios'; import authHeader from './auth-header'; const API_URL = 'http://localhost:8080/api/test/'; class UserService { getPublicContent() { return axios.get(API_URL + 'all'); } getUserBoard() { return axios.get(API_URL + 'user', { headers: authHeader() }); } getModeratorBoard() { return axios.get(API_URL + 'mod', { headers: authHeader() }); } getAdminBoard() { return axios.get(API_URL + 'admin', { headers: authHeader() }); } } export default new UserService(); ================================================ FILE: src/store/auth.module.js ================================================ import AuthService from '../services/auth.service'; const user = JSON.parse(localStorage.getItem('user')); const initialState = user ? { status: { loggedIn: true }, user } : { status: { loggedIn: false }, user: null }; export const auth = { namespaced: true, state: initialState, actions: { login({ commit }, user) { return AuthService.login(user).then( user => { commit('loginSuccess', user); return Promise.resolve(user); }, error => { commit('loginFailure'); return Promise.reject(error); } ); }, logout({ commit }) { AuthService.logout(); commit('logout'); }, register({ commit }, user) { return AuthService.register(user).then( response => { commit('registerSuccess'); return Promise.resolve(response.data); }, error => { commit('registerFailure'); return Promise.reject(error); } ); } }, mutations: { loginSuccess(state, user) { state.status.loggedIn = true; state.user = user; }, loginFailure(state) { state.status.loggedIn = false; state.user = null; }, logout(state) { state.status.loggedIn = false; state.user = null; }, registerSuccess(state) { state.status.loggedIn = false; }, registerFailure(state) { state.status.loggedIn = false; } } }; ================================================ FILE: src/store/index.js ================================================ import { createStore } from "vuex"; import { auth } from "./auth.module"; const store = createStore({ modules: { auth, }, }); export default store; ================================================ FILE: vue.config.js ================================================ module.exports = { devServer: { port: 8081 } }