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 相关文章推荐
js中格式化日期时间型数据函数代码
Nov 08 Javascript
JsDom 编程小结
Aug 09 Javascript
基于JavaScript实现继承机制之构造函数方法对象冒充的使用详解
May 07 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
Javascript页面添加到收藏夹的简单方法
Aug 07 Javascript
Javascript执行效率全面总结
Nov 04 Javascript
javascript实现的简单的表单验证
Jul 10 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
Sep 18 Javascript
浅析Vue.js 中的条件渲染指令
Nov 19 Javascript
微信小程序日历插件代码实例
Dec 04 Javascript
JavaScript实现简单日历效果
Sep 11 Javascript
JavaScript 声明私有变量的两种方式
Feb 05 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
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
codeigniter集成ucenter1.6双向通信的解决办法
2014/06/12 PHP
成为好程序员必须避免的5个坏习惯
2014/07/04 PHP
php实现的Timer页面运行时间监测类
2014/09/24 PHP
图文介绍PHP添加Redis模块及连接
2015/07/28 PHP
深入浅析PHP7.0新特征(五大新特征)
2015/10/29 PHP
Yii核心验证器api详解
2016/11/23 PHP
高性能Javascript笔记 数据的存储与访问性能优化
2012/08/02 Javascript
解决IE6的PNG透明JS插件使用介绍
2013/04/17 Javascript
js 数值转换为3位逗号分隔的示例代码
2014/02/19 Javascript
nodejs教程之环境安装及运行
2014/11/21 NodeJs
nodejs中实现路由功能
2014/12/29 NodeJs
JavaScript实现把数字转换成中文
2015/06/29 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
PassWord输入框代码分享
2016/06/07 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
vue监听input标签的value值方法
2018/08/27 Javascript
通过seajs实现JavaScript的模块开发及按模块加载
2019/06/06 Javascript
vue中全局路由守卫中替代this操作(this.$store/this.$vux)
2020/07/24 Javascript
vue Treeselect下拉树只能选择第N级元素实现代码
2020/08/31 Javascript
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
python 实现对文件夹内的文件排序编号
2018/04/12 Python
Python3读取Excel数据存入MySQL的方法
2018/05/04 Python
python 对key为时间的dict排序方法
2018/10/17 Python
详解Django admin高级用法
2019/11/06 Python
Django 解决distinct无法去除重复数据的问题
2020/05/20 Python
python3实现简单飞机大战
2020/11/29 Python
利用Python实现自动扫雷小脚本
2020/12/17 Python
意大利在线高尔夫商店:Online Golf
2021/03/09 全球购物
描述内存分配方式以及它们的区别
2016/10/15 面试题
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
教师国庆节演讲稿范文2014
2014/09/21 职场文书
2014大学生学生会工作总结
2014/12/19 职场文书
家属联谊会致辞
2015/07/31 职场文书