koa和vue实现单点登录__前端__Vue.js
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
theme: cyanosis highlight: github
单点登录
使用的是
iframe
和postMessage
的方式
主要用到的技术点:
- vue
- koa
- jwt
- mongodb
- iframe+postMessage
实现单点登录的大体流程
- 创建一个ssoclient项目,这个项目只有登录功能。
- 创建一个ssoserver项目,后端项目提供登录接口验证。
- 创建一个companyclient项目,暂时只写前端。
代码实现
1、ssoclient项目
我们需要实现一个登录的功能,简单实现就好,本堂可的主要目的是了解如何进行单点登录。
封装请求api
安装axios
yarn add axios
npm install axios
util/request.js
import axios from "axios";
const _axios = axios.create({
baseURL: '/api',
timeout:10000
});
// 添加请求拦截器
_axios.interceptors.request.use((config)=> {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
_axios.interceptors.response.use((response)=>{
// 对响应数据做点什么
let data = response.data;
console.log(response)
if(response.status === 200){
return data;
}
return Promise.reject(data.msg);
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
export default _axios;
全局挂载axios请求,main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from "./util/request";
Vue.config.productionTip = false
Vue.prototype.$axios = axios;
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
Login.vue
<template>
<div>
<input v-model="email" placeholder="请输入邮箱"/>
<input type="password" v-model="password" placeholder="请输入密码"/>
<button @click="toLogin">登录</button>
</div>
</template>
<script>
export default {
data(){
return {
email:'linlin@qq.com',
password:'123456',
redirectUrl:''
}
},
created(){
let search = window.location.search
if(search == '' || !search.includes('?')){
console.log('没有回调的URL')
} else {
let str = window.location.search.split('?')[1];
console.log(str)
this.redirectUrl = decodeURIComponent(str.split("=")[1]);
console.log(this.redirectUrl)
}
},
methods:{
toLogin(){
this.$axios({
url:'/api/users/login',
method:'post',
data:{
email:this.email,
password:this.password
}
}).then(res=>{
console.log(res)
window.localStorage.setItem('token',res.token)
if(this.redirectUrl){
window.location.href = this.redirectUrl;
} else {
this.$router.push({name:'About'})
}
}).catch(res=>{
})
}
}
}
</script>
vue.config.js
module.exports = {
devServer: {
open:true,
port:'8000',
proxy: {
'/api': {
target: 'http://localhost:8888/', //API服务器的地址
ws: true, // 代理websockets
changeOrigin: true, // 虚拟的站点需要更换origin
pathRewrite: { //重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
'^/api': ''
}
}
},
}
}
我们需要用koa搭建一个能登录,且能做token验证的服务器。
创建一个需要被单点登录的vue项目companyclient
在ssoclient
里添加postMessage
发送消息
这段代码也可以改到vueRouter的全局守卫里。
export default {
name: 'Home',
beforeCreate(){
//fromcompany需要用这个字段判断是否接收这个message消息,token是我们之前登录后存进去的
window.parent.postMessage({from:'sso.com',token:localStorage.getItem('token')},'*')
}
}
companyclient
新建一个token.js
util/token.js
这段代码其实可以写在vueRouter
全局守卫里
window.addEventListener('message',function(e){
console.log('iframe收到消息了')
if(e.data.from === 'sso.com'){
if(e.data.token){
console.log(e.data.token)
localStorage.setItem('token',e.data.token);
} else {
let redirectUrl = window.location.href
location.href=`http://localhost:8000/login?redirectUrl=${redirectUrl}`
}
}
})
let iframe = document.createElement('iframe');
iframe.width = 0;
iframe.height = 0;
iframe.style.display = 'none'
iframe.src = "http://localhost:8000"
document.body.appendChild(iframe);
main.js里面引用
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './util/token'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 作者: YaYa 原文链接:https://juejin.im/post/7012410335734792206