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

- Signup Page:

- Form Validation could look like this:

- Login Page & Profile Page (for successful Login):

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
================================================
{{currentUser.username}} Profile
Token:
{{currentUser.accessToken.substring(0, 20)}} ... {{currentUser.accessToken.substr(currentUser.accessToken.length - 20)}}
Id:
{{currentUser.id}}
Email:
{{currentUser.email}}
Authorities:
================================================
FILE: src/components/Register.vue
================================================
{{ message }}
================================================
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
}
}