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中的parseInt使用技巧
Sep 03 Javascript
js判断输入是否为正整数、浮点数等数字的函数代码
Nov 17 Javascript
JavaScript的parseInt 取整使用
May 09 Javascript
js闭包实例汇总
Nov 09 Javascript
javascript中对变量类型的判断方法
Aug 09 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
React Native模块之Permissions权限申请的实例相机
Sep 28 Javascript
记一次webpack3升级webpack4的踩坑经历
Jun 12 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 Javascript
jQuery开发仿QQ版音乐播放器
Jul 10 jQuery
js实现幻灯片轮播图
Aug 14 Javascript
OpenLayers3实现地图显示功能
Sep 25 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程序时遇到的三个问题
2012/01/17 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
PHP把数字转成人民币大写的函数分享
2014/06/30 PHP
php switch语句多个值匹配同一代码块应用示例
2014/07/29 PHP
php中session_id()函数详细介绍,会话id生成过程及session id长度
2015/09/23 PHP
php pdo连接数据库操作示例
2019/11/18 PHP
各种常用浏览器getBoundingClientRect的解析
2009/05/21 Javascript
js移动端事件基础及常用事件库详解
2017/08/15 Javascript
vue安装和使用scss及sass与scss的区别详解
2018/10/15 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
2018/11/10 Javascript
vue+高德地图写地图选址组件的方法
2019/05/18 Javascript
微信小程序自定义单项选择器样式
2019/07/25 Javascript
vue el-tree 默认展开第一个节点的实现代码
2020/05/15 Javascript
微信小程序学习总结(五)常见问题实例小结
2020/06/04 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
2020/06/08 Javascript
python常见的格式化输出小结
2016/12/15 Python
tensorflow建立一个简单的神经网络的方法
2018/02/10 Python
Python基于sklearn库的分类算法简单应用示例
2018/07/09 Python
Python面向对象之继承和组合用法实例分析
2018/08/27 Python
利用Python实现手机短信监控通知的方法
2019/07/22 Python
Python读取实时数据流示例
2019/12/02 Python
numpy.ndarray 实现对特定行或列取值
2019/12/05 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
Mac中PyCharm配置Anaconda环境的方法
2020/03/04 Python
Django实现前台上传并显示图片功能
2020/05/29 Python
Python中过滤字符串列表的方法
2020/12/22 Python
传统HTML页面实现模块化加载的方法
2018/10/15 HTML / CSS
html5-websocket基于远程方法调用的数据交互实现
2012/12/04 HTML / CSS
美国汽配连锁巨头Pep Boys官网:轮胎更换、汽车维修服务和汽车零部件
2017/01/14 全球购物
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
中学生运动会入场词
2014/02/12 职场文书
保护环境建议书400字
2014/05/13 职场文书
美国旅游签证工作证明
2014/10/14 职场文书
2014年纪检工作总结
2014/11/12 职场文书
普通员工辞职信范文
2015/05/12 职场文书
Java基于Dijkstra算法实现校园导游程序
2022/03/17 Java/Android