利用cube-ui與$store和token的Demo

Login.vue

// Login.vue
<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="haneldValidate"
>
</cube-form>
</div>

分別設置model和schema

model: { username: "", passwd: "" },
schema: {
fields: [
{
type: "input",
modelKey: "username",
label: "用戶名",
props: {
placeholder: "請輸入用戶名"
},
rules: {
// 校驗規則
required: true
},
trigger: "blur"
},
]
}

發起登陸請求,Login.vuevue

this.$store
.dispatch("login", this.model)
.then(success => {})
.catch(error => {});

登陸動做,store.js

import us from "./service/user";
login({ commit }, model) {
return us.login(model).then(res => {
const {token} = res.data;
if (token) {
localStorage.setItem("token", token);
commit("setLoginState", true);
return true;
}
return false;
});
}

接口服務,service/user.js

import axios from "axios";
export default {
login(user) {
return axios.get("/api/login", {params: user});
}
};

vue.config.js中,模擬接口

configureWebpack:{
devServer:{
before(app){
app.get("/api/login", function(req, res) {
const { username, passwd } = req.query;
console.log(username, passwd);
if (username == "kaikeba" && passwd == "123") {
res.json({ code: 1, token: "jilei" });
} else {
res
.status(401)
.json({ code: 0, message: "用戶名或者密碼錯誤" });
}
});
}
}
}

http攔截器

有了token以後,每次http請求發出,都要加載header上ios

// interceptor.js
const axios = require("axios");
export default function() {
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.token = token;
}
return config;
});
}
// 啓用,main.js
import interceptor from './interceptor'
interceptor();

接口驗證

// mock接口,vue.config.js
function auth(req, res, next) {
if (req.headers.token) {
// 已認證
next()
} else {
res.sendStatus(401)
}
}
app.get("/api/userinfo", auth, function(req, res) {
res.json({ code: 1, data: { name: "tom", age: 20 } });
});

http攔截響應

// interceptor.js
export default function(vm) { // 傳入vue實例
// ...
// 響應攔截
axios.interceptors.response.use(null, err => {
if (err.response.status === 401) {
// 清空vuex和localstorage
vm.$store.dispatch("logout");
// 跳轉login
vm.$router.push("/login");
}
return Promise.reject(err);
});
}

令牌機制\

服務端,~/server/server.jsweb

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.config.js

devServer: {
//代理配置
proxy: {
"/api": {
target: "http://127.0.0.1:3000/",
changOrigin: true
}
},
// before(app) { ... }
}

攔截器處的修改,interceptor.js

config.headers.Authorization = 'Bearer ' + token;
相關文章
相關標籤/搜索