vue中的使用token的方法示例


Posted in Javascript onMarch 10, 2020

初始于登录页面

Home.vue

<template>
 <div class="home">
 </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
import axios from 'axios';

export default {
 name: 'home',
 components: {
  HelloWorld
 },
 created(){
  axios.get('/api/userinfo').then(res=>console.log(res.data))
 }
}
</script>

About.vue

<template>
 <div class="about">
  <h1>This is an about page</h1>
 </div>
</template>

login.vue

<template>
 <div>
  <div class="logo">
   <img src="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>
export default {
 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) {
       const path = this.$route.query.redirect || '/'
       this.$router.push(path)
     }
   }).catch(error => {
     const toast = this.$createToast({
       time:2000,
       txt:'登录失败',
       type:'error'
     }).show();
   });
  }
 }
};
</script>

<style scoped>
</style>

/service/user

import axios from "axios";

export default {
 login(user) {
  return axios.get("/api/login", { params: user })
   .then(({ data }) => data);
 }
};

App.vue

<template>
 <div id="app">
  <div id="nav">
   <router-link to="/">Home</router-link> |
   <router-link to="/about">About</router-link>
   <button v-if="$store.state.user.isLogin" @click="logout">注销</button>
  </div>
  <router-view/>
 </div>
</template>

<script>
export default {
 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

import Vue from 'vue'

// By default we import all the components.
// Only reserve the components on demand and remove the rest.
// Style is always required.
import {
 /* eslint-disable no-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
/// picker style
$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
// checkbox hollow
$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
// radio hollow
$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 := 0 0 6px 2px $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

import axios from "axios";

export default function(vm) {
 axios.interceptors.request.use(config => {
  const token = localStorage.getItem("token");
  if (token) {
   config.headers.Authorization = "Bearer " + token;
  }
  return config;
 });

 axios.interceptors.response.use(null, err => {
  if (err.response.status === 401) {
   // 清空
   vm.$store.dispatch("logout");
   // 跳转
   vm.$router.push("/login");
  }
  return Promise.reject(err);
 });
}

路由守卫 路由 router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import Login from "./views/Login.vue";

Vue.use(Router);

const router = new Router({
 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 },
   // 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")
  }
 ]
});

router.beforeEach((to, from, next) => {
 if (to.meta.auth) {
  // 只要本地有token就认为登录了
  const token = localStorage.getItem("token");
  if (token) {
   next();
  } else {
   // 未登录
   next({
    path: "/login",
    query: { redirect: to.path }
   });
  }
 } else {
  next();
 }
});

export default router;

mock数据 或mock-easy vue.config.js

module.exports = {
 css: {
  loaderOptions: {
   stylus: {
    "resolve url": 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: "用户名或密码错误" });
   //   }
   //  });

   // 中间件函数
   //  function auth(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

import user from './user'

Vue.use(Vuex)

export default new Vuex.Store({
 modules: {user}
})

user.js

import us from '@/service/user'

export default {
  state: {
    isLogin: !!localStorage.getItem("token")
  },
  mutations: {
    setLoginState(state, val) {
      state.isLogin = val;
    }
  },
  actions: {
    login({commit}, userInfo) {
      return us.login(userInfo).then(({token}) => {
        // code, token
        if (token) {
          // 登录成功
          commit('setLoginState', true)
          localStorage.setItem('token', token)
          return true
        }
        return false
      })
    },
    logout({commit}){
      localStorage.removeItem('token')
      commit('setLoginState', false)
    }
  }
}

gitignore

.DS_Store
node_modules
/dist

# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

main.js

import Vue from 'vue'
import './cube-ui'
import App from './App.vue'
import store from './store'
import router from './router'
import interceptor from './interceptor'

Vue.config.productionTip = false

const app = new Vue({
 store,
 router,
 render: h => h(App)
}).$mount('#app');

interceptor(app);

vue中的使用token的方法示例

深入理解令牌机制

Bearer Token规范
概念:描述在http访问OAuth2保护资源时如何使用令牌的规范
特点:令牌就是身份证明,无需证明令牌的所有权
具体规定:在请求头中定义Authorization

Authorization: Bearer <token>

Json Web Token规范
概念:令牌的具体定义方式
规定:令牌由三部分构成 “头”,“载荷”,“签名”
头:包含加密算法。令牌类型等信息
载荷:包含用户信息。签发时间和过期时间等信息,base64编码
签名:根据头 和载荷及秘钥加密得到的哈希串Hmac Sha1 256

server/server.js

const Koa = require("koa");
const Router = require("koa-router");
const jwt = require("jsonwebtoken");
const jwtAuth = require("koa-jwt");
const secret = "it's a secret";
const app = new Koa();
const router = new Router();
router.get("/api/login", async ctx => {
const { username, passwd } = ctx.query;
console.log(username, passwd);
if (username == "kaikeba" && passwd == "123") {
// 生成令牌
const token = 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 }),
async ctx => {
ctx.body = { code: 1, data: { name: "jerry", age: 20 } };
}
);
app.use(router.routes());
app.listen(3000);

到此这篇关于vue中的使用token的方法示例的文章就介绍到这了,更多相关vue使用token内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
一些javascript一些题目的解析
Dec 25 Javascript
JQuery 自定义CircleAnimation,Animate方法学习笔记
Jul 10 Javascript
js形成页面的一种遮罩效果实例代码
Jan 04 Javascript
禁止拷贝网页内容的js代码
Jan 22 Javascript
js和jquery设置disabled属性为true使按钮失效
Aug 07 Javascript
jquery实现的下拉和收缩效果示例
Aug 21 Javascript
node.js中的fs.fsync方法使用说明
Dec 15 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
Apr 01 Javascript
纯JS实现轮播图
Feb 22 Javascript
微信小程序wx.previewImage预览图片实例详解
Dec 07 Javascript
详解服务端预渲染之Nuxt(介绍篇)
Apr 07 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 #Javascript
JS如何在数组指定位置插入元素
Mar 10 #Javascript
vue实现简单瀑布流布局
May 28 #Javascript
JavaScript观察者模式原理与用法实例详解
Mar 10 #Javascript
微信小程序用canvas画图并分享
Mar 09 #Javascript
JavaScript实现简单贪吃蛇效果
Mar 09 #Javascript
原生js无缝轮播插件使用详解
Mar 09 #Javascript
You might like
用php的ob_start来生成静态页面的方法分析
2011/03/09 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
PHP基于数组实现的分页函数实例
2014/08/20 PHP
YII使用url组件美化管理的方法
2015/12/28 PHP
ThinkPHP使用Smarty第三方插件方法小结
2016/03/19 PHP
php实现当前页面点击下载文件的简单方法
2016/09/22 PHP
PHP实现生成带背景的图形验证码功能
2016/10/03 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
jquery 为a标签绑定click事件示例代码
2014/06/23 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
2015/08/12 Javascript
jQuery超简单选项卡完整实例
2015/09/26 Javascript
Javascript的表单与验证-非空验证
2016/03/18 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
js实现简单的选项卡效果
2017/02/23 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
jQuery+koa2实现简单的Ajax请求的示例
2018/03/06 jQuery
vue弹窗组件使用方法
2018/04/28 Javascript
在微信小程序里使用watch和computed的方法
2018/08/02 Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
2019/05/17 jQuery
Python获取远程文件大小的函数代码分享
2014/05/13 Python
浅析python中SQLAlchemy排序的一个坑
2017/02/24 Python
Django框架实现的普通登录案例【使用POST方法】
2019/05/15 Python
使用python3调用wxpy模块监控linux日志并定时发送消息给群组或好友
2019/06/05 Python
django url到views参数传递的实例
2019/07/19 Python
pygame实现成语填空游戏
2019/10/29 Python
python文件编写好后如何实践
2020/07/07 Python
史上最详细的Python打包成exe文件教程
2021/01/17 Python
德国滑雪和户外用品网上商店:XSPO
2019/10/30 全球购物
心理健康教育心得体会
2013/12/29 职场文书
农民工讨薪标语
2014/06/26 职场文书
2014年小学班主任工作总结
2014/11/08 职场文书
委托书英文
2015/01/28 职场文书
小学生暑假生活总结
2015/07/13 职场文书
解析目标检测之IoU
2021/06/26 Python