如何在vue中使用token
这期内容当中小编将会给大家带来有关如何在vue中使用token,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
初始于登录页面
Home.vue
<template> <divclass="home"> </div> </template> <script> //@isanaliasto/src importHelloWorldfrom'@/components/HelloWorld.vue' importaxiosfrom'axios'; exportdefault{ name:'home', components:{ HelloWorld }, created(){ axios.get('/api/userinfo').then(res=>console.log(res.data)) } } </script>
About.vue
<template> <divclass="about"> <h2>Thisisanaboutpage</h2> </div> </template>
login.vue
<template> <div> <divclass="logo"> <imgsrc="https://img.kaikeba.com/logo-new.png"alt> </div> <!--<cube-button>登录</cube-button>--> <cube-form :model="model" :schema="schema" @submit.prevent="handleLogin" @validate="handleValidate" ></cube-form> </div> </template> <script> exportdefault{ data(){ return{ model:{ username:"", password:"" }, schema:{ fields:[ { type:"input", modelKey:"username", label:"用户名", props:{placeholder:"请输入用户名"}, rules:{ required:true }, trigger:"blur" }, { type:"input", modelKey:"password", label:"密码", props:{ placeholder:"请输入密码", type:"password", eye:{open:true} }, rules:{ required:true }, trigger:"blur" }, { type:"submit", label:"登录" } ] } }; }, methods:{ handleValidate(ret){ console.log(ret); }, handleLogin(e){ //登录请求 this.$store.dispatch("login",this.model).then(success=>{ if(success){ constpath=this.$route.query.redirect||'/' this.$router.push(path) } }).catch(error=>{ consttoast=this.$createToast({ time:2000, txt:'登录失败', type:'error' }).show(); }); } } }; </script> <stylescoped> </style>
/service/user
importaxiosfrom"axios"; exportdefault{ login(user){ returnaxios.get("/api/login",{params:user}) .then(({data})=>data); } };
App.vue
<template> <divid="app"> <divid="nav"> <router-linkto="/">Home</router-link>| <router-linkto="/about">About</router-link> <buttonv-if="$store.state.user.isLogin"@click="logout">注销</button> </div> <router-view/> </div> </template> <script> exportdefault{ methods:{ logout(){ this.$store.dispatch('logout') } }, } </script> <style> #app{ font-family:"Avenir",Helvetica,Arial,sans-serif; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; text-align:center; color:#2c3e50; } </style>
cube-ui组件的引用 cube-ui.js
importVuefrom'vue' //Bydefaultweimportallthecomponents. //Onlyreservethecomponentsondemandandremovetherest. //Styleisalwaysrequired. import{ /*eslint-disableno-unused-vars*/ Style, //basic Button, Loading, Tip, Toolbar, TabBar, TabPanels, //form Checkbox, CheckboxGroup, Checker, Radio, RadioGroup, Input, Textarea, Select, Switch, Rate, Validator, Upload, Form, //popup Popup, Toast, Picker, CascadePicker, DatePicker, TimePicker, SegmentPicker, Dialog, ActionSheet, Drawer, ImagePreview, //scroll Scroll, Slide, IndexList, Swipe, Sticky, ScrollNav, ScrollNavBar }from'cube-ui' Vue.use(Button) Vue.use(Loading) Vue.use(Tip) Vue.use(Toolbar) Vue.use(TabBar) Vue.use(TabPanels) Vue.use(Checkbox) Vue.use(CheckboxGroup) Vue.use(Checker) Vue.use(Radio) Vue.use(RadioGroup) Vue.use(Input) Vue.use(Textarea) Vue.use(Select) Vue.use(Switch) Vue.use(Rate) Vue.use(Validator) Vue.use(Upload) Vue.use(Form) Vue.use(Popup) Vue.use(Toast) Vue.use(Picker) Vue.use(CascadePicker) Vue.use(DatePicker) Vue.use(TimePicker) Vue.use(SegmentPicker) Vue.use(Dialog) Vue.use(ActionSheet) Vue.use(Drawer) Vue.use(ImagePreview) Vue.use(Scroll) Vue.use(Slide) Vue.use(IndexList) Vue.use(Swipe) Vue.use(Sticky) Vue.use(ScrollNav) Vue.use(ScrollNavBar)
cube-ui的样式 theme.styl
@require"~cube-ui/src/common/stylus/var/color.styl" //action-sheet $action-sheet-color:=$color-grey $action-sheet-active-color:=$color-orange $action-sheet-bgc:=$color-white $action-sheet-active-bgc:=$color-light-grey-opacity $action-sheet-title-color:=$color-dark-grey $action-sheet-space-bgc:=$color-mask-bg ///pickerstyle $action-sheet-picker-cancel-color:=$color-light-grey $action-sheet-picker-cancel-active-color:=$color-light-grey-s //bubble //button $btn-color:=$color-white $btn-bgc:=$color-regular-blue $btn-bdc:=$color-regular-blue $btn-active-bgc:=$color-blue $btn-active-bdc:=$color-blue $btn-disabled-color:=$color-white $btn-disabled-bgc:=$color-light-grey-s $btn-disabled-bdc:=$color-light-grey-s ///primary $btn-primary-color:=$color-white $btn-primary-bgc:=$color-orange $btn-primary-bdc:=$color-orange $btn-primary-active-bgc:=$color-dark-orange $btn-primary-active-bdc:=$color-dark-orange ///light $btn-light-color:=$color-grey $btn-light-bgc:=$color-light-grey-sss $btn-light-bdc:=$color-light-grey-sss $btn-light-active-bgc:=$color-active-grey $btn-light-active-bdc:=$color-active-grey ///outline $btn-outline-color:=$color-grey $btn-outline-bgc:=transparent $btn-outline-bdc:=$color-grey $btn-outline-active-bgc:=$color-grey-opacity $btn-outline-active-bdc:=$color-grey ///outline-primary $btn-outline-primary-color:=$color-orange $btn-outline-primary-bgc:=transparent $btn-outline-primary-bdc:=$color-orange $btn-outline-primary-active-bgc:=$color-orange-opacity $btn-outline-primary-active-bdc:=$color-dark-orange //toolbar $toolbar-bgc:=$color-light-grey-sss $toolbar-active-bgc:=$color-active-grey //checkbox $checkbox-color:=$color-grey $checkbox-icon-color:=$color-light-grey-s ///checked $checkbox-checked-icon-color:=$color-orange $checkbox-checked-icon-bgc:=$color-white ///disabled $checkbox-disabled-icon-color:=$color-light-grey-ss $checkbox-disabled-icon-bgc:=$color-light-grey-ss //checkboxhollow $checkbox-hollow-checked-icon-color:=$color-orange $checkbox-hollow-disabled-icon-color:=$color-light-grey-ss //checkbox-group $checkbox-group-bgc:=$color-white $checkbox-group-horizontal-bdc:=$color-light-grey-s //radio $radio-group-bgc:=$color-white $radio-group-horizontal-bdc:=$color-light-grey-s $radio-color:=$color-grey $radio-icon-color:=$color-light-grey-s ///selected $radio-selected-icon-color:=$color-white $radio-selected-icon-bgc:=$color-orange ///disabled $radio-disabled-icon-bgc:=$color-light-grey-ss //radiohollow $radio-hollow-selected-icon-color:=$color-orange $radio-hollow-disabled-icon-color:=$color-light-grey-ss //dialog $dialog-color:=$color-grey $dialog-bgc:=$color-white $dialog-icon-color:=$color-regular-blue $dialog-icon-bgc:=$color-background $dialog-title-color:=$color-dark-grey $dialog-close-color:=$color-light-grey $dialog-btn-color:=$color-light-grey $dialog-btn-bgc:=$color-white $dialog-btn-active-bgc:=$color-light-grey-opacity $dialog-btn-highlight-color:=$color-orange $dialog-btn-highlight-active-bgc:=$color-light-orange-opacity $dialog-btn-disabled-color:=$color-light-grey $dialog-btn-disabled-active-bgc:=transparent $dialog-btns-split-color:=$color-row-line //index-list $index-list-bgc:=$color-white $index-list-title-color:=$color-dark-grey $index-list-anchor-color:=$color-light-grey $index-list-anchor-bgc:=#f7f7f7 $index-list-item-color:=$color-dark-grey $index-list-item-active-bgc:=$color-light-grey-opacity $index-list-nav-color:=$color-grey $index-list-nav-active-color:=$color-orange //loading //picker $picker-bgc:=$color-white $picker-title-color:=$color-dark-grey $picker-subtitle-color:=$color-light-grey $picker-confirm-btn-color:=$color-orange $picker-confirm-btn-active-color:=$color-light-orange $picker-cancel-btn-color:=$color-light-grey $picker-cancel-btn-active-color:=$color-light-grey-s $picker-item-color:=$color-dark-grey //popup $popup-mask-bgc:=rgb(37,38,45) $popup-mask-opacity:=.4 //scroll //slide $slide-dot-bgc:=$color-light-grey-s $slide-dot-active-bgc:=$color-orange //time-picker //tip $tip-color:=$color-white $tip-bgc:=$color-dark-grey-opacity //toast $toast-color:=$color-light-grey-s $toast-bgc:=rgba(37,38,45,0.9) //upload $upload-btn-color:=$color-grey $upload-btn-bgc:=$color-white $upload-btn-active-bgc:=$color-light-grey-opacity $upload-btn-box-shadow:=006px2px$color-grey-opacity $upload-btn-border-color:=#e5e5e5 $upload-file-bgc:=$color-white $upload-file-remove-color:=rgba(0,0,0,.8) $upload-file-remove-bgc:=$color-white $upload-file-state-bgc:=$color-mask-bg $upload-file-success-color:=$color-orange $upload-file-error-color:=#f43530 $upload-file-status-bgc:=$color-white $upload-file-progress-color:=$color-white //switch $switch-on-bgc:=$color-orange $switch-off-bgc:=$color-white $switch-off-border-color:=#e4e4e4 //input $input-color:=$color-grey $input-bgc:=$color-white $input-border-color:=$color-row-line $input-focus-border-color:=$color-orange $input-placeholder-color:=$color-light-grey-s $input-clear-icon-color:=$color-light-grey //textarea $textarea-color:=$color-grey $textarea-bgc:=$color-white $textarea-border-color:=$color-row-line $textarea-focus-border-color:=$color-orange $textarea-outline-color:=$color-orange $textarea-placeholder-color:=$color-light-grey-s $textarea-indicator-color:=$color-light-grey-s //validator $validator-msg-def-color:=#e64340 //select $select-color:=$color-grey $select-bgc:=$color-white $select-disabled-color:=#b8b8b8 $select-disabled-bgc:=$color-light-grey-opacity $select-border-color:=$color-light-grey-s $select-border-active-color:=$color-orange $select-icon-color:=$color-light-grey $select-placeholder-color:=$color-light-grey-s //swipe $swipe-btn-color:=$color-white //form $form-color:=$color-grey $form-bgc:=$color-white $form-invalid-color:=#e64340 $form-group-legend-color:=$color-light-grey $form-group-legend-bgc:=$color-background $form-label-required-color:=#e64340 //drawer $drawer-color:=$color-dark-grey $drawer-title-bdc:=$color-light-grey-ss $drawer-title-bgc:=$color-white $drawer-panel-bgc:=$color-white $drawer-item-active-bgc:=$color-light-grey-opacity //scroll-nav $scroll-nav-bgc:=$color-white $scroll-nav-color:=$color-grey $scroll-nav-active-color:=$color-orange //image-preview $image-preview-counter-color:=$color-white //tab-bar&tab-panel $tab-color:=$color-grey $tab-active-color:=$color-dark-orange $tab-slider-bgc:=$color-dark-orange
axios 请求响应拦截器 interceptor.js
importaxiosfrom"axios"; exportdefaultfunction(vm){ axios.interceptors.request.use(config=>{ consttoken=localStorage.getItem("token"); if(token){ config.headers.Authorization="Bearer"+token; } returnconfig; }); axios.interceptors.response.use(null,err=>{ if(err.response.status===401){ //清空 vm.$store.dispatch("logout"); //跳转 vm.$router.push("/login"); } returnPromise.reject(err); }); }
路由守卫 路由 router.js
importVuefrom"vue"; importRouterfrom"vue-router"; importHomefrom"./views/Home.vue"; importLoginfrom"./views/Login.vue"; Vue.use(Router); constrouter=newRouter({ mode:"history", base:process.env.BASE_URL, routes:[ { path:"/", name:"home", component:Home }, { path:"/login", name:"login", component:Login }, { path:"/about", name:"about", meta:{auth:true}, //routelevelcode-splitting //thisgeneratesaseparatechunk(about.[hash].js)forthisroute //whichislazy-loadedwhentherouteisvisited. component:()=> import(/*webpackChunkName:"about"*/"./views/About.vue") } ] }); router.beforeEach((to,from,next)=>{ if(to.meta.auth){ //只要本地有token就认为登录了 consttoken=localStorage.getItem("token"); if(token){ next(); }else{ //未登录 next({ path:"/login", query:{redirect:to.path} }); } }else{ next(); } }); exportdefaultrouter;
mock数据 或mock-easy vue.config.js
module.exports={ css:{ loaderOptions:{ stylus:{ "resolveurl":true, import:["./src/theme"] } } }, pluginOptions:{ "cube-ui":{ postCompile:true, theme:false } }, configureWebpack:{ devServer:{ proxy:{ "/api":{ target:"http://127.0.0.1:3000/", changOrigin:true } }, //before(app){ //app.get("/api/login",(req,res)=>{ //const{username,password}=req.query; //if(username==="kaikeba"&&password==="123"){ //res.json({code:1,token:"jilei"}); //}else{ //res.status(401).json({code:0,message:"用户名或密码错误"}); //} //}); //中间件函数 //functionauth(req,res,next){ //if(req.headers.token){ //next(); //}else{ //res.status(401);如果设置这个只是设置状态,并没有返回前端,会导致前端等待状态 res.sendStatus(401)这个正确的 //} //} //app.get("/api/userinfo",auth,(req,res)=>{ //res.json({code:1,data:{name:"Jerry"}}); //}); //} } } };
登录动作,store.js
index.js
importuserfrom'./user' Vue.use(Vuex) exportdefaultnewVuex.Store({ modules:{user} })
user.js
importusfrom'@/service/user' exportdefault{ state:{ isLogin:!!localStorage.getItem("token") }, mutations:{ setLoginState(state,val){ state.isLogin=val; } }, actions:{ login({commit},userInfo){ returnus.login(userInfo).then(({token})=>{ //code,token if(token){ //登录成功 commit('setLoginState',true) localStorage.setItem('token',token) returntrue } returnfalse }) }, logout({commit}){ localStorage.removeItem('token') commit('setLoginState',false) } } }
gitignore
.DS_Store node_modules /dist #localenvfiles .env.local .env.*.local #Logfiles npm-debug.log* yarn-debug.log* yarn-error.log* #Editordirectoriesandfiles .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw*
main.js
importVuefrom'vue' import'./cube-ui' importAppfrom'./App.vue' importstorefrom'./store' importrouterfrom'./router' importinterceptorfrom'./interceptor' Vue.config.productionTip=false constapp=newVue({ store, router, render:h=>h(App) }).$mount('#app'); interceptor(app);
深入理解令牌机制
Bearer Token规范概念:描述在http访问OAuth3保护资源时如何使用令牌的规范特点:令牌就是身份证明,无需证明令牌的所有权具体规定:在请求头中定义Authorization
Authorization:Bearer<token>
Json Web Token规范概念:令牌的具体定义方式规定:令牌由三部分构成 “头”,“载荷”,“签名”头:包含加密算法。令牌类型等信息载荷:包含用户信息。签发时间和过期时间等信息,base64编码签名:根据头 和载荷及秘钥加密得到的哈希串Hmac Sha1 256
server/server.js
constKoa=require("koa"); constRouter=require("koa-router"); constjwt=require("jsonwebtoken"); constjwtAuth=require("koa-jwt"); constsecret="it'sasecret"; constapp=newKoa(); constrouter=newRouter(); router.get("/api/login",asyncctx=>{ const{username,passwd}=ctx.query; console.log(username,passwd); if(username=="kaikeba"&&passwd=="123"){ //生成令牌 consttoken=jwt.sign( { data:{name:"kaikeba"},//用户信息数据 exp:Math.floor(Date.now()/1000)+60*60//过期时}, secret ); ctx.body={code:1,token}; }else{ ctx.status=401; ctx.body={code:0,message:"用户名或者密码错误"}; } }); router.get( "/api/userinfo", jwtAuth({secret}), asyncctx=>{ ctx.body={code:1,data:{name:"jerry",age:20}}; } ); app.use(router.routes()); app.listen(3000);
上述就是小编为大家分享的如何在vue中使用token了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注恰卡编程网行业资讯频道。
推荐阅读
-
Vue组件的自定义事件和全局事件总线怎么使用
-
vue中消息订阅与发布如何使用
vue中消息订阅与发布如何使用这篇文章主要介绍“vue中消息订阅与...
-
Vue显示图片的方式有哪些
-
vue引入静态jquery报错如何解决
vue引入静态jquery报错如何解决这篇文章主要介绍“vue引入...
-
vue-cropper怎么实现裁剪图片
-
怎么用Vue+NodeJS实现大文件上传
-
Vue如何实现简易跑马灯效果
-
Vue怎么指定不编译的文件夹和favicon.ico
Vue怎么指定不编译的文件夹和favicon.ico这篇文章主要介...
-
Vue中的插槽怎么使用
-
Vue WebPack怎么忽略指定文件或目录