├── .gitignore
├── README.md
├── babel.config.js
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
└── src
├── App.vue
├── assets
└── logo.png
├── components
└── NavBar.vue
├── main.js
├── router
└── index.js
├── store
├── index.js
└── modules
│ └── auth.js
└── views
├── Home.vue
├── Login.vue
├── Posts.vue
└── Register.vue
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # auth-project
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
26 | ### Description on Blog Post
27 | See [Smashing Magazine](https://www.smashingmagazine.com/2020/10/authentication-in-vue-js/)
28 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "auth-project",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^0.20.0",
12 | "core-js": "^3.6.5",
13 | "vue": "^2.6.11",
14 | "vue-cookies": "^1.7.4",
15 | "vue-router": "^3.2.0",
16 | "vuex": "^3.5.1",
17 | "vuex-persistedstate": "^4.0.0-beta.1"
18 | },
19 | "devDependencies": {
20 | "@vue/cli-plugin-babel": "~4.5.0",
21 | "@vue/cli-plugin-eslint": "~4.5.0",
22 | "@vue/cli-plugin-router": "^4.5.6",
23 | "@vue/cli-service": "~4.5.0",
24 | "babel-eslint": "^10.1.0",
25 | "eslint": "^6.7.2",
26 | "eslint-plugin-vue": "^6.2.2",
27 | "vue-template-compiler": "^2.6.11"
28 | },
29 | "eslintConfig": {
30 | "root": true,
31 | "env": {
32 | "node": true
33 | },
34 | "extends": [
35 | "plugin:vue/essential",
36 | "eslint:recommended"
37 | ],
38 | "parserOptions": {
39 | "parser": "babel-eslint"
40 | },
41 | "rules": {}
42 | },
43 | "browserslist": [
44 | "> 1%",
45 | "last 2 versions",
46 | "not dead"
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gabbyprecious/vue-blog/fbf85084eac873666ba93b78b799d3de4767bc71/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
18 |
19 |
28 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gabbyprecious/vue-blog/fbf85084eac873666ba93b78b799d3de4767bc71/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/NavBar.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Home |
4 |
Posts |
5 |
6 | Logout
7 |
8 |
9 | Register |
10 | Login
11 |
12 |
13 |
14 |
30 |
31 |
49 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import App from "./App.vue";
3 | import router from "./router";
4 | import store from "./store";
5 | import axios from "axios";
6 |
7 | axios.defaults.withCredentials = true;
8 | axios.defaults.baseURL = "https://gabbyblog-97f6eaccfce4.herokuapp.com/";
9 |
10 | axios.interceptors.response.use(undefined, function(error) {
11 | if (error) {
12 | const originalRequest = error.config;
13 | if (error.response.status === 401 && !originalRequest._retry) {
14 | originalRequest._retry = true;
15 | store.dispatch("LogOut");
16 | return router.push("/login");
17 | }
18 | }
19 | });
20 |
21 | Vue.config.productionTip = false;
22 |
23 | new Vue({
24 | store,
25 | router,
26 | render: (h) => h(App),
27 | }).$mount("#app");
28 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import VueRouter from "vue-router";
3 | import store from "../store";
4 | import Home from "../views/Home.vue";
5 | import Register from "../views/Register";
6 | import Login from "../views/Login";
7 | import Posts from "../views/Posts";
8 |
9 | Vue.use(VueRouter);
10 |
11 | const routes = [
12 | {
13 | path: "/",
14 | name: "Home",
15 | component: Home,
16 | },
17 | {
18 | path: "/register",
19 | name: "Register",
20 | component: Register,
21 | meta: { guest: true },
22 | },
23 | {
24 | path: "/login",
25 | name: "Login",
26 | component: Login,
27 | meta: { guest: true },
28 | },
29 | {
30 | path: "/posts",
31 | name: "Posts",
32 | component: Posts,
33 | meta: { requiresAuth: true },
34 | },
35 | ];
36 |
37 | const router = new VueRouter({
38 | mode: "history",
39 | base: process.env.BASE_URL,
40 | routes,
41 | });
42 |
43 | router.beforeEach((to, from, next) => {
44 | if (to.matched.some((record) => record.meta.requiresAuth)) {
45 | if (store.getters.isAuthenticated) {
46 | next();
47 | return;
48 | }
49 | next("/login");
50 | } else {
51 | next();
52 | }
53 | });
54 |
55 | router.beforeEach((to, from, next) => {
56 | if (to.matched.some((record) => record.meta.guest)) {
57 | if (store.getters.isAuthenticated) {
58 | next("/posts");
59 | return;
60 | }
61 | next();
62 | } else {
63 | next();
64 | }
65 | });
66 |
67 | export default router;
68 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vuex from "vuex";
2 | import Vue from "vue";
3 | import createPersistedState from "vuex-persistedstate";
4 | import auth from "./modules/auth";
5 |
6 | // Load Vuex
7 | Vue.use(Vuex);
8 |
9 | // Create store
10 | export default new Vuex.Store({
11 | modules: {
12 | auth,
13 | },
14 | plugins: [createPersistedState()],
15 | });
16 |
--------------------------------------------------------------------------------
/src/store/modules/auth.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | const state = {
4 | user: null,
5 | posts: null,
6 | };
7 |
8 | const getters = {
9 | isAuthenticated: (state) => !!state.user,
10 | StatePosts: (state) => state.posts,
11 | StateUser: (state) => state.user,
12 | };
13 |
14 | const actions = {
15 | async Register({dispatch}, form) {
16 | await axios.post('register', form)
17 | let UserForm = new FormData()
18 | UserForm.append('username', form.username)
19 | UserForm.append('password', form.password)
20 | await dispatch('LogIn', UserForm)
21 | },
22 |
23 | async LogIn({commit}, user) {
24 | await axios.post("login", user);
25 | await commit("setUser", user.get("username"));
26 | },
27 |
28 | async CreatePost({ dispatch }, post) {
29 | await axios.post("post", post);
30 | return await dispatch("GetPosts");
31 | },
32 |
33 | async GetPosts({ commit }) {
34 | let response = await axios.get("posts");
35 | commit("setPosts", response.data);
36 | },
37 |
38 | async LogOut({ commit }) {
39 | let user = null;
40 | commit("logout", user);
41 | },
42 | };
43 |
44 | const mutations = {
45 | setUser(state, username) {
46 | state.user = username;
47 | },
48 |
49 | setPosts(state, posts) {
50 | state.posts = posts;
51 | },
52 | logout(state, user) {
53 | state.user = user;
54 | },
55 | };
56 |
57 | export default {
58 | state,
59 | getters,
60 | actions,
61 | mutations,
62 | };
63 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Heyyyyyy welcome to our blog, check out our posts
4 |
5 |
6 |
7 |
13 |
--------------------------------------------------------------------------------
/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
Username or Password is incorrect
16 |
17 |
18 |
19 |
20 |
52 |
53 |
85 |
--------------------------------------------------------------------------------
/src/views/Posts.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
22 |
23 |
24 | -
25 |
26 |
{{ post.title }}
27 |
{{ post.write_up }}
28 |
Written By: {{ post.author.username }}
29 |
30 |
31 |
32 |
33 |
Oh no!!! We have no posts
34 |
35 |
36 |
37 |
70 |
124 |
--------------------------------------------------------------------------------
/src/views/Register.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
Username already exists
21 |
22 |
23 |
24 |
54 |
86 |
--------------------------------------------------------------------------------