<dd id="t699n"></dd>

  • <em id="t699n"></em>

    1. <dd id="t699n"></dd>

      基于vue導航守衛和veux的登陸及退出實例

      時間:2021-08-23 11:29:14 類型:vue
      字號:    

      一. 安裝vuex及永久化vuex)

           npm i vuex

           npm install --save vuex-persistedstate

           在 src 目錄下 創建 "store" 文件夾, 并在文件夾下創建index.js文件, 代碼如下:

      import Vue from 'vue';
      import Vuex from 'vuex';
      import createPersistedState from 'vuex-persistedstate';
      Vue.use(Vuex); 
      const state = {
      		'token'    : ''
      };
      const mutations = {
      		changeToken(state,params){
      			state.token = params;
      		}
      		
      };
      
      
      const store = new Vuex.Store({
         plugins:[createPersistedState()],
         state : state, //狀態管理
         mutations:mutations, //修改state
         modules:{} //模塊
      });
       
      export default store;
      
      //main.js文件引入
      import store from './store';

      二. 安裝Element組件 及axios組件

           npm i element-ui -S

         npm install axios --save

           main.js文件引入

      import ElementUI from 'element-ui';
      import 'element-ui/lib/theme-chalk/index.css';
      Vue.use(ElementUI);
      
      import axios from 'axios';
      
      axios.defaults.baseURL='
      
      new Vue({
        router,
        store, //注入,組件中可以使用 this.$store 獲取
        render: h => h(App)
      }).$mount('#app');

      三. views下創建login.vue組件, 代碼如下:

      <template>
      		<div>
      			<Header></Header>
      			<el-form ref="form"  label-width="80px" class="form">
      			  <el-form-item label="用戶名">
      			    <el-input v-model="form.username" clearable></el-input>
      			  </el-form-item>
      			  <el-form-item label="密碼" >
      			    <el-input v-model="form.userpwd" show-password></el-input>
      			  </el-form-item>
      			 
      			  <el-form-item>
      			    <el-button type="primary" @click="login">登陸</el-button>
      			    <el-button>取消</el-button>
      			  </el-form-item>
      			</el-form>
      		</div>
      </template>
      
      <script>
      	console.log(localStorage.getItem('preRoute'));
      	import Header from "@/components/Header"
      	export default{
      		data() {
      		      return {
      		        form: {
      		          username: '',
      				  userpwd : ''
      		        },
      		      }
      		},
      		components:{
      			Header
      		},
      		methods:{
      			login(){
      				if(this.form.username == ''){
      					this.$message({ message: '用戶名不能為空', type: 'warning',offset:200});
      					return false;
      				}
      				if(this.form.userpwd == ''){
      					this.$message({ message: '用戶密碼不能為空', type: 'warning',offset:200});
      					return false;
      				}
      				// console.log(this.form);
      				// return ;
      				this.axios.post("loginCheck",{params:this.form}).then(res=>{
      					let _this =  this;
      					if(res.data.code == 1){
      						this.$store.commit("changeToken",res.data.token);
      						
      						
      						this.$message({
      						          message: '登陸成功',
      						          type: 'success',
      								  offset:200,
      								  onClose:()=>{
      									// Object.keys(_this.data).forEach(key=>{_this.data[key]=''})
      								  }
      						        });
      						const curr = localStorage.getItem('preRoute')
      						if (curr == null) {
      							this.$router.push({ path: "/" });
      						} else {
      							this.$router.push({ path: curr });//跳轉到來源頁面
      						}
      					}
      					else{
      						this.$message({
      						          message: '賬號密碼不正確',
      						          type: 'warning',
      								  offset:200
      						        });
      					}
      					
      				})
      			}
      		}
      	}
      </script>
      
      <style>
      	.form{
      		width:300px;
      		margin: 20px auto;
      	}
      </style>

      四. 創建安全退出文件Exit.vue

      <template>
      		<div>
      			<Header></Header>
      		</div>
      </template>
      
      <script>
      	import Header from "@/components/Header"
      	export default{
      			components:{
      				Header
      			},
      			mounted(){
      				this.$store.commit("changeToken","");
      				this.$message({
      				  message: '安全退出',
      				  type: 'success',
      				  offset:200,
      				  onClose:()=>{
      				          this.$router.push({ path: "/"});                         //此處寫提示關閉后需要執行的函數
      				   }
      				});
      				
      			}
      		}
      </script>

      五, 配置路由及導航守衛

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import Home from '../views/Home.vue'
      import Store from '../store'
      import axios from 'axios';
      
      Vue.use(VueRouter)
      
      const routes = [
        {
          path: '/',
          name: 'Home',
          component: Home,
      	 meta: {login_require:true}
        },
        {
          path: '/contact',
          name: 'Cantact',
          component:()=>import('../views/Contact.vue'),
      	 meta: {login_require:true}
        },
        {
      	  path:'/message',
      	  name:'Message',
      	  component:()=>import('../views/Message.vue'),
      	   meta: {login_require:true}
        },
        {
      	  path:'/about',
      	  name:'About',
      	  component:()=>import('../views/About.vue'),
      	   meta: {login_require:true}
        },
        {
      	  path:'/news',
      	  name:'News',
      	  component:()=>import("../views/News.vue"),
      	   meta: {login_require:true}
        },
        {
      	  path:'/newsdetail',
      	  name:'Newsdetail',
      	  component:()=>import("../views/Newsdetail.vue"),
      	   meta: {login_require:true}
        },
        {
      	  path:'/vuexx',
      	  name:'Vuexx',
      	  component:() => import('../views/Vuexx.vue'),
      	   meta: {login_require:true}
      	 
        },
        {
        	  path:'/vuea',
        	  name:'Vuea',
        	  component:() => import('../views/Vuea.vue'),
      	   meta: {login_require:true}
        	 
        },
        {
      	  path:'/eleform',
      	  name:'Eleform',
      	  component:()=> import('../views/Eleform.vue'),
      	   meta: {login_require:true}
        },
        {
      	  path:'/mysecret',
      	  name:'Mysecret',
      	  component:()=> import('../views/mysecret.vue'),
      	  meta: {login_require:false}
        },
        {
      	  path:'/login',
      	  name:"Login",
      	  component:()=> import('../views/login.vue'),
      	  meta: {login_require:true}
        },
        {
      	  path:'/exit',
      	  name:"Exit",
      	  component:()=> import('../views/Exit.vue'),
      	   meta: {login_require:true}
        }
      ]
      
      const router = new VueRouter({
        routes
      })
      router.beforeEach((to,from,next)=>{
      	let token = Store.state.token;
      	if ((to.matched.some(function (item) {
      			return item.meta.login_require
      	  }))) {
      	    next();
      	  } 
      	else {
      		if(token == ""){
      			//沒有得到token, 所以去登陸
      			localStorage.setItem("preRoute", router.currentRoute.fullPath); //保存當前路徑 
      			if(to.path == "/login" || to.path == "/exit"){
      				next();
      			}
      			else{
      				next("/login");
      			}
      		}
      		else{
      			//有了token值, 然后判斷是否是正確的, 有沒有過期等
      			axios({
      			    method: 'get',
      			    url: "http://ggqvue.cn/vue/jwtTokenVerify",
      			    headers: { 'Authorization': token }
      				//params:{token:token}
      			  }).then(res => {
      			     if(res.data.code == 2){ //驗證有問題
      				    // console.log("驗證不通過");
      					 localStorage.setItem("preRoute", router.currentRoute.fullPath)
      					 if(to.path == "/login" || to.path == "/exit"){
      					 	next();
      					 }
      					 else{
      					 	next("/login");
      					 }
      				 }
      				 else{
      					// console.log("驗證通過");
      					 next();
      				 }
      			  }).catch(e => {
      			  	
      			  })
      			  
      			
      		}
      	}
          
       })
      export default router

         六. 后臺登陸及token驗證

        public function loginCheck(){
              $post = $this->request->post("params");
              // halt($post);
              //模擬比較, 實際應用中通常 從數據庫中查詢比對
              if($post["username"] == "admin" && $post["userpwd"] == "123456"){
                   $payload=[
                      'iss'=>'莊子',
                      'iat'=>time(),
                      'exp'=>time()+7200,
                      'nbf'=>time(),
                      'sub'=>'用戶登陸操作',
                      'jti'=>md5(uniqid('JWT').time()),
                      "username"=>$post["username"]
                  ];
                  $token=\Jwt::getToken($payload);
                  return json(["code"=>1, "mes"=>"登陸成功","token"=>$token]);
              }
              else{
                   return json(["code"=>2, "mes"=>"登陸失敗"]);
              }
          }
      
           public function jwtTokenVerify(){
      
                  $token = $this->request->header("Authorization");
                 //對token進行驗證簽名
                  $result = \Jwt::verifyToken($token);
                  if($result["code"] == 1){
                      return json(["code"=>1,"mes"=>"success", "username"=>$result["payload"]["username"]]);
                  }
                  else{
                      return json(["code"=>2,"mes"=>"fail"]);
                  }
          }

      注意: php端解決跨域操作的方法,在入口文件中加入以下內容:

      header("Access-Control-Allow-Origin:*");
      header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE");
      header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding,Authorization");

      效果如下:


      黄网站免费 <