日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue项目登录及token验证 vue-ant

發布時間:2023/12/9 vue 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue项目登录及token验证 vue-ant 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在前后端完全分離的情況下,Vue項目中實現token驗證大致思路如下:

1、第一次登錄的時候,前端調后端的登陸接口,發送用戶名和密碼

2、后端收到請求,驗證用戶名和密碼,驗證成功,就給前端返回一個token

3、前端拿到token,將token存儲到localStorage和vuex中,并跳轉路由頁面

4、前端每次跳轉路由,就判斷 localStroage 中有無 token ,沒有就跳轉到登錄頁面,有則跳轉到對應路由頁面

5、每次調后端接口,都要在請求頭中加token

6、后端判斷請求頭中有無token,有token,就拿到token并驗證token,驗證成功就返回數據,驗證失敗(例如:token過期)就返回401,請求頭中沒有token也返回401

7、如果前端拿到狀態碼為401,就清除token信息并跳轉到登錄頁面

.
.
.
.
實操代碼:

1.login頁(賬號密碼登錄完成后,將后臺返回的token儲存到本地);最后附上了登錄頁完整代碼

handleSubmit(e) {var that = this;this.userName = this.userName.trim();this.password = this.password.trim();if (this.userName === "" && this.password === "") {that.$message.warning("賬號和密碼無內容");return;}if (this.userName === "") {that.$message.warning("賬號無內容");return;}if (this.password === "") {that.$message.warning("密碼無內容");return;}var username = document.getElementById("username").value;var password = document.getElementById("password").value;e.preventDefault();this.form.validateFields((err, values) => {//這一步將用戶名儲存在vuex ||||||||||目前域賬號和用戶名都是寫一樣了||||||||||||||||||||||||||||||||||||||||||||||||axios.post(this.$store.state.windowCONTENT + "sysConfig/getUserRole", {loginUser: this.userName,}).then((res) => {if (res.data.success == 0) {//有權限this.$store.state.loginUser = this.userName;this.$store.state.userName = this.userName;this.$store.state.roleCode = res.data.data.roleCode;//存入tokenlocalStorage.setItem("token",JSON.stringify(res.data.data.token));// console.log(res.data.data,this.$store.state.roleCode);if (!err) {this.$router.push("/layout");this.$message.success("登陸成功");}} else {//無權限this.$message.error(res.data.data);}});});},

2.marn.js(配置請求攔截器,每次請求攜帶token,后端進行驗證;配置響應攔截器,根據后端驗證返回的結果,判斷token是否過期)

import "babel-polyfill"; import Vue from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; import { Button, message } from 'ant-design-vue'; import Antd from "ant-design-vue"; import "ant-design-vue/dist/antd.css"; import zh_CN from "ant-design-vue/lib/locale-provider/zh_CN"; import moment from "moment"; import "moment/locale/zh-cn"; import "./assets/iconfont/iconfont"; import axios from "axios";Vue.component(Button.name, Button);Vue.config.productionTip = false;Vue.use(Antd); Vue.prototype.$message = message;// 設置axios全局默認的BASE-URL, 只要設置了全局的默認base_url,以后的請求會自動拼接上base_url //axios.defaults.baseURL = 'http://localhost:8888/api/private/v1/'// 配置axios的請求攔截器-(每次在請求頭上攜帶后臺分配的token-后臺判斷token是否有效等問題) axios.interceptors.request.use(function(config) {// 在發送請求之前做些什么// console.log('請求到了喲', config.headers.Authorization)// 統一的給config設置 tokenconfig.headers.Authorization = JSON.parse(localStorage.getItem("token"));config.headers['Token'] = JSON.parse(localStorage.getItem("token"));return config;},function(error) {// 對請求錯誤做些什么return Promise.reject(error);} );//響應攔截器 與后端定義狀態是100時候是錯誤 跳轉到登錄界面 axios.interceptors.response.use(function (response) {// 對響應數據做點什么console.log(response)//當返回信息為未登錄或者登錄失效的時候重定向為登錄頁面if (response.data.status == 100 || response.data.message == '用戶未登錄或登錄超時,請登錄!') {router.push({path: "/login",querry: { redirect: router.currentRoute.fullPath }//從哪個頁面跳轉})message.warning(response.data.message);}return response; }, function (error) {// 對響應錯誤做點什么return Promise.reject(error) })moment.locale("zh-cn"); new Vue({zh_CN,router,watch: {// 監聽路由變化"$route.path": function(newVal, oldVal) {console.log(`new_path = ${newVal}, old_path = ${oldVal}`);},},store,render: (h) => h(App), }).$mount("#app");

3.router.js(配置導航守衛,有token或者是去登錄頁就通過,否則定向到登錄頁)

import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import Layout from '../components/Layout.vue' import Login from '../components/Login.vue'Vue.use(VueRouter)const routes = [{path: '/',redirect: 'login'},{path: '/login',name: 'Login',component: Login},{path: '/layout',name: 'Layout',component: Layout},{path: '/about',name: 'About',// 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/About.vue')} ]const router = new VueRouter({routes })// to 到哪去 // from 從哪來 // next 是否放行 next() 放行 next('/login') 攔截到登錄 // 如果準備去登錄, 不需要攔截 // 如果已經登錄過了, 有token, 不需要攔截 // 如果不是去登陸, 且沒有 token, 攔截到登錄頁 router.beforeEach((to, from, next) => {const token = JSON.parse(localStorage.getItem('token'));console.log(token);// console.log(to)if (to.path === '/login' || token) {next()} else {next('/login')} })export default router

4.退出:清除本地儲存的token

//退出登錄signOut() {console.log("點擊了退出", this.$route.query.sessionId);localStorage.clear("token");this.$route.push('/')//將vuex的數據初始化和清除默認的數據},

.
.
.
.
.
.

完整登錄頁

<template><div class="login"><div class="logo"><img :src="logoUrl" alt /></div><div class="welcome">WELCOME</div><div class="platform">歡迎來到XX平臺</div><div class="box"><a-formid="components-form-demo-normal-login":form="form"class="login-form"@submit.prevent="handleSubmit"><a-form-item><div class="l-bor">登錄</div></a-form-item><a-form-item><div class="account">賬號</div></a-form-item><a-form-item><a-input v-model="userName" allowClear class="user-name" placeholder="請輸入"><!-- v-decorator="['userName',{ rules: [{ required: true, message: '請輸入賬號名!' }] },]"--><a-icon slot="prefix" type="user" style="color: rgba(0,0,0,.25)" /></a-input></a-form-item><a-form-item><div class="p-box">密碼</div></a-form-item><a-form-item><!-- <a-inputv-decorator="['password',{ rules: [{ required: true, message: 'Please input your Password!' }] },]"type="password"placeholder="Password"><a-icon slot="prefix" type="lock" style="color: rgba(0,0,0,.25)" /></a-input>--><a-input-passwordv-model="password"allowClearclass="password"type="password"placeholder="請輸入"><!-- v-decorator="['password',{ rules: [{ required: true, message: '請輸入密碼!' }] },]"--><a-icon slot="prefix" type="lock" style="color: rgba(0,0,0,.25)" /></a-input-password></a-form-item><a-form-item><!-- <a-checkboxv-decorator="['remember',{valuePropName: 'checked',initialValue: true,},]">Remember me</a-checkbox>--><!-- <a class="login-form-forgot" href>Forgot password</a> --><a-button:style="{opacity: (btnFlag ? .5 : 1)}"type="primary"html-type="submit"class="login-form-button"><spanstyle="width:58px;height:24px;font-size:17px;font-family:PingFang-SC-Light,PingFang-SC;font-weight:300;color:rgba(255,255,255,1);line-height:24px;text-shadow:0px 2px 3px rgba(62,32,201,0.1);">登錄</span></a-button><!-- Or --><!-- <a href>register now!</a> --></a-form-item></a-form></div><div class="bottom"></div></div> </template><script> import axios from "axios"; export default {data() {return {logoUrl: require("../assets/logo.svg"),userName: "",password: "",btnFlag: true,flagColor: {opacity: 0.5,},};},beforeCreate() {this.form = this.$form.createForm(this, { name: "normal_login" });},created() {},methods: {handleSubmit(e) {var that = this;this.userName = this.userName.trim();this.password = this.password.trim();if (this.userName === "" && this.password === "") {that.$message.warning("賬號和密碼無內容");return;}if (this.userName === "") {that.$message.warning("賬號無內容");return;}if (this.password === "") {that.$message.warning("密碼無內容");return;}// jucenter.submit({name:this.userName,pwd:this.password});e.preventDefault();this.form.validateFields((err, values) => {//這一步將用戶名儲存在vuex ||||||||||目前域賬號和用戶名都是寫一樣了||||||||||||||||||||||||||||||||||||||||||||||||console.log(this.userName, this.password);axios.post(this.$store.state.windowCONTENT + "sysConfig/getUserRole",{loginUser: this.userName}).then(res => {if (res.data.success == 0) {//有權限this.$store.state.loginUser = this.loginUser;this.$store.state.userName = res.data.data.userName;this.$store.state.roleCode = res.data.data.roleCode;//存入tokenlocalStorage.setItem("token",JSON.stringify(res.data.data.token));if (!err) {this.$router.push("/layout");console.log(111);this.$message.success('登陸成功')}} else {//無權限this.$message.error(res.data.data)}})});},},watch: {userName: function (v1, v2) {var that = this;if (v1 && this.password) {this.btnFlag = false;console.log(this.btnFlag);} else {this.btnFlag = true;console.log(this.btnFlag);}},password: function (v1, v2) {var that = this;if (v1 && this.userName) {this.btnFlag = false;console.log(this.btnFlag);} else {this.btnFlag = true;console.log(this.btnFlag);}},}, }; </script> <style lang="less"> .login {position: relative;text-align: left;height: 100%;background: linear-gradient(154deg,rgba(119, 182, 244, 1) 0%,rgba(66, 106, 229, 1) 100%);// background-color: pink!important;// overflow: hidden;.logo {position: absolute;top: 21px;left: 35px;}.welcome {position: absolute;bottom: 60%;left: 10%;width: 416px;height: 100px;font-size: 72px;font-family: PingFang-SC-Regular, PingFang-SC;font-weight: 400;color: rgba(255, 255, 255, 1);line-height: 100px;letter-spacing: 6px;}.platform {position: absolute;bottom: 53%;left: 10%;width: 313px;height: 33px;font-size: 24px;font-family: PingFang-SC-Light, PingFang-SC;font-weight: 300;color: rgba(255, 255, 255, 1);line-height: 33px;letter-spacing: 2px;}.box {position: absolute;bottom: 10%;right: 0;// margin: 0 auto;// margin-bottom: 151px; //定位高度-----↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓margin-right: 21%;width: 370px;height: 500px;border-radius: 10px;background: rgba(252, 251, 255, 1);padding: 0px 53px;//去除默認下邊距.ant-form-item {margin-bottom: 0;}//輸入框.ant-input-affix-wrapper .ant-input:not(:last-child) {height: 36px;font-size: 14px;font-family: PingFang-SC-Regular, PingFang-SC;font-weight: 400;color: rgba(53, 58, 64, 1);// background-color: pink;}//登錄按鈕#components-form-demo-normal-login .login-form-button {width: 264px;height: 44px;background: linear-gradient(90deg,rgba(60, 163, 247, 1) 0%,rgba(28, 106, 235, 1) 100%);box-shadow: 0px 2px 3px 0px rgba(62, 32, 201, 0.1);border-radius: 6px;}.l-bor {margin-left: -53px;margin-top: 50px;line-height: 25px;border-left: 6px solid rgba(28, 106, 235, 1);padding-left: 47px;font-size: 18px;font-family: PingFang-SC-Medium, PingFang-SC;font-weight: 500;color: rgba(53, 58, 64, 1);letter-spacing: 1px;}// .account{// margin-top: 58px;// width:27px;// height:17px;// font-size:12px;// font-family:PingFang-SC-Light,PingFang-SC;// font-weight:300;// color:rgba(53,58,64,1);// line-height:17px;// letter-spacing:1px;// }.ant-form-item:nth-child(2) {position: absolute;top: 133px;.account {width: 27px;height: 17px;font-size: 12px;font-family: PingFang-SC-Light, PingFang-SC;font-weight: 300;color: rgba(53, 58, 64, 1);line-height: 17px;letter-spacing: 1px;}}.ant-form-item:nth-child(3) {position: absolute;top: 160px;width: 264px;}.ant-form-item:nth-child(4) {position: absolute;top: 230px;width: 264px;.p-box {width: 27px;height: 17px;font-size: 12px;font-family: PingFang-SC-Light, PingFang-SC;font-weight: 300;color: rgba(53, 58, 64, 1);line-height: 17px;letter-spacing: 1px;}}.ant-form-item:nth-child(5) {position: absolute;top: 257px;width: 264px;}.ant-form-item:nth-child(6) {position: absolute;top: 376px;width: 264px;}}.bottom {position: absolute;bottom: 0;width: 100%;// height: 151px; //固定高度-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑height: 10%; //固定高度-----↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑background: linear-gradient(360deg,rgba(75, 118, 232, 0) 0%,rgba(57, 98, 224, 0.41) 100%);} } #components-form-demo-normal-login .login-form {max-width: 300px; } #components-form-demo-normal-login .login-form-forgot {float: right; } #components-form-demo-normal-login .login-form-button {width: 100%; } </style>

總結

以上是生活随笔為你收集整理的vue项目登录及token验证 vue-ant的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。