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 相关文章推荐
jquery之Document元素选择器篇
Aug 14 Javascript
写得不错的jquery table鼠标经过变色代码
Sep 27 Javascript
jquery datepicker参数介绍和示例
Apr 15 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
Oct 22 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
Oct 30 Javascript
重新认识vue之事件阻止冒泡的实现
Aug 02 Javascript
微信小程序获取用户openid的实现
Dec 24 Javascript
详解Vue之父子组件传值
Apr 01 Javascript
js实现的格式化数字和金额功能简单示例
Jul 30 Javascript
layer 关闭指定弹出层的例子
Sep 25 Javascript
vue中动态select的使用方法示例
Oct 28 Javascript
MutationObserver在页面水印实现起到的作用详解
Jul 07 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 方便水印和缩略图的图形类
2009/05/21 PHP
解析php中static,const与define的使用区别
2013/06/18 PHP
php生成excel列序号代码实例
2013/12/24 PHP
ThinkPHP3.2框架自定义配置和加载用法示例
2018/06/14 PHP
PHP中非常有用却鲜有人知的函数集锦
2019/08/17 PHP
克隆javascript对象的三个方法小结
2011/01/12 Javascript
腾讯UED 漂亮的提示信息效果代码
2011/09/12 Javascript
容易造成JavaScript内存泄露几个方面
2014/09/04 Javascript
Node.js 去掉种子(torrent)文件里的邪恶信息
2015/03/27 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
2015/10/13 Javascript
js调用webservice构造SOAP进行身份验证
2016/04/27 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
2017/01/20 Javascript
jQuery.ajax向后台传递数组问题的解决方法
2017/05/12 jQuery
JavaScript实现的搜索及高亮显示功能示例
2017/08/14 Javascript
vue的一个分页组件的示例代码
2017/12/25 Javascript
ES6基础之默认参数值
2019/02/21 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
Vue——解决报错 Computed property &quot;****&quot; was assigned to but it has no setter.
2020/12/19 Vue.js
python解决字典中的值是列表问题的方法
2013/03/04 Python
Python类属性的延迟计算
2016/10/22 Python
Python之日期与时间处理模块(date和datetime)
2017/02/16 Python
解决python3中解压zip文件是文件名乱码的问题
2018/03/22 Python
Python+OpenCV感兴趣区域ROI提取方法
2019/01/10 Python
python 求1-100之间的奇数或者偶数之和的实例
2019/06/11 Python
django admin 自定义替换change页面模板的方法
2019/08/23 Python
使用Keras训练好的.h5模型来测试一个实例
2020/07/06 Python
Omio荷兰:预订火车、巴士和机票
2018/11/04 全球购物
如何获得EntityManager
2014/02/09 面试题
医院辞职信范文
2014/01/17 职场文书
幼儿园元旦活动感言
2014/03/02 职场文书
公共机构节能宣传周活动总结
2014/07/09 职场文书
党性观念心得体会
2014/09/03 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书
IDEA 链接Mysql数据库并执行查询操作的完整代码
2021/05/20 MySQL
详解CSS故障艺术
2021/05/25 HTML / CSS