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>
相关文章
|
3月前
|
JSON 算法 安全
Nest.js JWT 验证授权管理
Nest.js JWT 验证授权管理
105 3
Nest.js JWT 验证授权管理
|
3月前
|
安全 Java 应用服务中间件
Shiro + JWT 进行登录验证
Shiro + JWT 进行登录验证
38 2
|
3天前
|
存储 前端开发 JavaScript
2022年超详细的SpringBoot+Vue+Jwt实现token的认证(重点部分讲解和完整的代码设计)
这篇文章详细介绍了使用SpringBoot、Vue.js和Jwt实现token认证的完整流程和代码设计,包括后端的jwt依赖引入、token生成和认证过滤器编写,以及前端的路由守卫、Vuex状态管理和token的存储与使用,确保用户登录状态的维护和验证。
|
6天前
|
Java Spring
JWT token验证后,通过 ThreadLocal 进行传值
JWT token验证后,通过 ThreadLocal 进行传值
6 0
|
1月前
|
JavaScript
vue 滑动拼图验证
vue 滑动拼图验证
15 1
vue 滑动拼图验证
|
2月前
|
JSON 算法 Go
go语言后端开发学习(一)——JWT的介绍以及基于JWT实现登录验证
go语言后端开发学习(一)——JWT的介绍以及基于JWT实现登录验证
1天搞定SpringBoot+Vue全栈开发 (9)JWT跨域认证
1天搞定SpringBoot+Vue全栈开发 (9)JWT跨域认证
|
3月前
|
前端开发 Java Spring
SpringBoot通过拦截器和JWT令牌实现登录验证
该文介绍了JWT工具类、匿名访问注解、JWT验证拦截器的实现以及拦截器注册。使用`java-jwt`库生成和验证JWT,JwtUtil类包含generateToken和verifyToken方法。自定义注解`@AllowAnon`允许接口匿名访问。JwtInterceptor在Spring MVC中拦截请求,检查JWT令牌有效性。InterceptorConfig配置拦截器,注册并设定拦截与排除规则。UserController示例展示了注册、登录(允许匿名)和需要验证的用户详情接口。
567 1
|
3月前
|
JSON 安全 关系型数据库
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证
SpringCloud Gateway 实现自定义全局过滤器 + JWT权限验证