vue与jwt验证

简介: vue与jwt验证

vue与jwt验证

简介:本文讲解,如何使用vue,对jwt进行验证。

后端部分看这篇文章:SpringBoot+JWT+Shiro

如何创建vue项目用命令窗口的方式创建Vue项目

这篇文章的代码可以在这里下载:jwt项目演示

数据库设计

前端代码

我前段所采取vue2+element-ui

element-ui组件

项目结构

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <router-view/>
  </div>
</template>
<style lang="scss">
</style>

index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
  {
    path: '/',
    name: 'login',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/login/LoginView.vue')
  },
  {
    path: '/register',
    name: 'register',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/register/RegisterView.vue')
  },
  {
    path: '/index',
    name: 'index',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/index/IndexView.vue')
  }
]
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})
export default router

store

index.js
import Vue from 'vue'
import Vuex from 'vuex'
import auth from './auth'
Vue.use(Vuex)
export default new Vuex.Store({
  modules: {
    auth: {
      namespaced: true, // 添加命名空间
      ...auth
    }
  }
})
auth.js
// auth.js
import axios from 'axios';
import router from '@/router';
const auth = {
  state: {
    token: null
  },
  mutations: {
    SET_TOKEN(state, token) {
      state.token = token;
    },
    CLEAR_TOKEN(state) {
      state.token = null;
    }
  },
  actions: {
    login({ commit }, loginForm) {
      return new Promise((resolve, reject) => {
        // 调用登录接口,传递登录表单数据
        axios.post('http://localhost:8989/user/login', loginForm)
          .then(response => {
            const token = response.data.data.token;
            // 将token保存到Vuex中
            commit('SET_TOKEN', token);
            // 将token保存到浏览器的localStorage中,以便在刷新页面后仍然可以保持登录状态
            localStorage.setItem('token', token);
            resolve();
          })
          .catch(error => {
            reject(error);
          });
      });
    },
    logout({ commit }) {
      // 清除token并重定向到登录页面
      commit('CLEAR_TOKEN');
      localStorage.removeItem('token');
      router.push('/');
    },
    checkToken({ commit }) {
      const token = localStorage.getItem('token');
      if (token) {
        // 将token保存到Vuex中
        commit('SET_TOKEN', token);
      } else {
        // 如果没有token,则重定向到登录页面
        router.push('/');
      }
    },        
  },
  getters: {
    getToken(state){
        console.log("我被调用了")        
        return state.token;
    }
  }
};
export default auth;

LoginView.vue

<template>
  <div class="login-container" style="display: flex; justify-content: center; align-items: center;">
    <el-card class="login-card">
      <h2 class="login-title">登录</h2>
      <el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-width="80px" class="login-form">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input>
        </el-form-item>
        <el-form-item>
          <div style="padding-left: 10%;">
            <el-button type="primary" @click="Login">登录</el-button>
            <span style="padding-left: 10%;">
              <el-link type="primary" @click="Register">注册</el-link>
            </span>
          </div>          
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>
<script>
import {mapActions } from 'vuex';
export default {
  data() {
    return {
      loginForm: {
        username: 'lihua2',
        password: '123456'
      },
      loginRules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' }
        ]
      }
    };
  },
  methods: {
    ...mapActions('auth', ['login']),
    Login() {
      // 验证表单
      this.$refs.loginForm.validate(valid => {
        console.log("表单验证成功")
        if (valid) {
          // 调用 auth 模块中的 login action
          this.login(this.loginForm)
            .then(() => {
              // 重定向到首页或其他页面
              this.$router.push('/index');
            })
            .catch(error => {
              console.log('登录失败:', error);
            });
        } else {
          console.log('表单验证失败');
        }
      });
    },
    Register() {
      this.$router.push('/register');
    }
  }
};
</script>
  <style scoped>
  .login-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
  }
  .login-card {
    width: 400px;
    padding: 20px;
  }
  .login-title {
    text-align: center;
    margin-bottom: 20px;
  }
  .login-form {
    margin-top: 20px;
  }
  </style>

IndexView.html

<template>
  <div>
    <el-button type="primary" @click="loginOut">退出</el-button>
    <el-table :data="users" style="width: 100%">
      <el-table-column prop="id" label="ID"></el-table-column>
      <el-table-column prop="username" label="Name"></el-table-column>
      <!-- 其他列... -->
    </el-table>
  </div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import axios from 'axios';
export default {
  data() {
    return {
      users: [],
    };
  },
  computed:{
    ...mapGetters('auth', ['getToken']),
    ...mapActions('auth', ['logout'])
  },
  mounted() {
    this.getAll();
  },
  methods: {
    getAll() {
      const token = this.getToken;
      console.log(token)
      axios.get(`http://localhost:8989/user/all/${token}`)
        .then(response => {
          this.users = response.data.data.data;
        })
        .catch(error => {
          console.error(error);
        });
    },
    loginOut(){
        this.logout()
        this.$router.push("/")
    }
  },
};
</script>

Register.vue

<template>
    <div class="register-container" style="display: flex; justify-content: center; align-items: center;">
      <el-card class="register-card">
        <h2 class="register-title">注册</h2>
        <el-form ref="registerForm" :model="registerForm" :rules="registerRules" label-width="80px" class="register-form">
          <el-form-item label="用户名" prop="username">
            <el-input v-model="registerForm.username" placeholder="请输入用户名"></el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input type="password" v-model="registerForm.password" placeholder="请输入密码"></el-input>
          </el-form-item>
          <el-form-item label="确认密码" prop="confirmPassword">
            <el-input type="password" v-model="registerForm.confirmPassword" placeholder="请再次输入密码"></el-input>
          </el-form-item>
          <el-form-item>
            <div style="padding-left: 10%;">
              <el-button type="primary" @click="Register">注册</el-button>
              <span style="padding-left: 10%;">
                <el-link type="primary" @click="Login">登录</el-link>
              </span>
            </div>          
          </el-form-item>
        </el-form>
      </el-card>
    </div>
  </template>
  <script>
  import axios from 'axios';
  export default {
    data() {
      return {
        registerForm: {
          username: '',
          password: '',
          confirmPassword: ''
        },
        registerRules: {
          username: [
            { required: true, message: '请输入用户名', trigger: 'blur' }
          ],
          password: [
            { required: true, message: '请输入密码', trigger: 'blur' }
          ],
          confirmPassword: [
            { required: true, message: '请再次输入密码', trigger: 'blur' },
            { validator: this.validateConfirmPassword, trigger: 'blur' }
          ]
        }
      };
    },
    methods: {
      Register() {
        const formData =        
        {
            username: this.registerForm.username,
            password: this.registerForm.password
        }
        this.$refs.registerForm.validate((valid) => {
          if (valid) {
            axios.post("http://localhost:8989/user/register", formData)
            .then(response => {
                if (response.data.code == 200){
                    console.log("注册成功")
                    alert("注册成功,现在返回登录页面>_<")
                    this.$router.push("/")
                } else {
                    alert(response.data.message)
                }
            })
          } else {
            console.log('Invalid registration form');
          }
        });
      },
      validateConfirmPassword(rule, value, callback) {
        if (value !== this.registerForm.password) {
          callback(new Error('两次输入的密码不一致'));
        } else {
          callback();
        }
      },
      Login() {
        this.$router.push("/")
      }
    }
  };
  </script>
  <style scoped>
  .register-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
  }
  .register-card {
    width: 400px;
    padding: 20px;
  }
  .register-title {
    text-align: center;
    font-size: 24px;
    margin-bottom: 20px;
  }
  .register-form {
    margin-top: 20px;
  }
  </style>
相关文章
|
8月前
|
存储 JSON JavaScript
Vue开发中Jwt的使用
Vue开发中Jwt的使用
116 0
|
9月前
|
JSON 算法 安全
Django JWT验证
Django JWT验证
131 0
|
23天前
|
JavaScript
vue 滑动拼图验证
vue 滑动拼图验证
13 1
vue 滑动拼图验证
1天搞定SpringBoot+Vue全栈开发 (9)JWT跨域认证
1天搞定SpringBoot+Vue全栈开发 (9)JWT跨域认证
|
2月前
|
JSON 安全 关系型数据库
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证
|
2月前
|
JSON 算法 前端开发
gin框架JWT验证实践(原理介绍,代码实践)
gin框架JWT验证实践(原理介绍,代码实践)
103 0
|
8月前
|
存储 安全 前端开发
深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
这篇文章讨论了认证和授权的概念,并探讨了设计权限认证框架的原则。它还比较了Cookie和Session的区别,并探讨了处理分布式部署时的Session保存问题。此外,文章还介绍了CSRF攻击及其防范方法,以及OAuth2.0、JWT令牌和SSO的概念。最后,文章提出了设计开放授权平台时需要考虑的因素。
129 0
深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计
|
8月前
|
存储 JSON JavaScript
Vue之Jwt的运用(一起探索JWT在Vue中的用途吧)
Vue之Jwt的运用(一起探索JWT在Vue中的用途吧)
120 0
|
8月前
|
JSON JavaScript 算法
[Vue]之Jwt的入门和Jwt工具类的使用及Jwt集成spa项目
[Vue]之Jwt的入门和Jwt工具类的使用及Jwt集成spa项目
117 0
|
9月前
|
JavaScript 前端开发 API
Vue 实现表单的增删改查功能及表单的验证
Vue 实现表单的增删改查功能及表单的验证
108 0