要想实现项目A授权登录到项目B,必须满足以下几个条件:
①项目A 需要有 项目B 的token,将token作为url参数进行跳转;
②项目B 开放与 login 同级的路径,不做拦截;
③项目B 从url中获取token,写入浏览器 Cookies 后自动获取登陆信息,即可完成授权;
router/index.js
import Vue from "vue";
import Router from "vue-router";
/**
* 不需要登录拦截的路由配置
*/
const loginIgnore = {
names: ["404", "403"], // 根据路由名称匹配
paths: ["/login", "/authorization"], // 根据路由fullPath匹配
/**
* 判断路由是否包含在该配置中
* @param route vue-router 的 route 对象
* @returns {boolean}
*/
includes(route) {
return this.names.includes(route.name) || this.paths.includes(route.path);
}
};
/**
* 初始化路由实例
* @returns {VueRouter}
*/
function initRouter() {
return new Router({
mode: "history",
routes: [{
path: "/login",
name: "login",
meta: {
title: "登录"
},
component: () => {
return import("@/pages/login/LoginBlank");
}
},
{
path:"/start",
name:"start",
component: () => {
return import("@/pages/StartView");
}
},
{
path: "/authorization",
name: "authorization",
meta: {
title: "项目A授权登录项目B"
},
component: () => {
return import("@/pages/authorization/Authorization");
}
},
{
path: "/404",
name: "exp404",
meta: {
title: "404页面"
},
component: () => {
return import("@/pages/exception/404");
}
},
{
path: "/500",
name: "exp500",
meta: {
title: "500页面"
},
component: () => {
return import("@/pages/exception/500");
}
},
{
path:"*",
redirect: "/404"
}]
});
}
export {loginIgnore, initRouter};router/guards.js
import { loginIgnore } from "@/router/index";
/**
* 登录守卫
* @param to
* @param from
* @param next
* @param options
*/
const loginGuard = (to, from, next, options) => {
const { message } = options;
if (!loginIgnore.includes(to) && !checkAuthorization()) {
message.warning("登录已失效,请重新登录");
next({ path: "/login" });
} else {
//已登录,获取登录用户资料
next();
}
};
export default {
beforeEach: [loginGuard]
};/pages/authorization/Authorization
<template>
<div class="authorize">
<div class="authorize-top" style="background: #0074FE;">
<img class="leftTopImg" src="https://gitee.com/lingxiu5858/assets/raw/master/img_authorize_rightBottom.png" alt="" />
<span class="authorize-title">授权登录</span>
<div class="authorize-content">
<div class="logo">
<div class="leftLogo">
<img src="" alt="">
<div class="title">项目A</div>
</div>
<div class="animation">
</div>
<div class="rightLogo">
<img src="" alt="">
<div class="title">项目B</div>
</div>
</div>
<div class="container">
<div class="authorize-text">
<div class="tips">即将登录项目B</div>
</div>
<div class="authorize-operation">
<div><a-button type="primary" @click="confirm" style="width: 364px; height: 40px; background: #0074FE;">确定</a-button></div>
<div><a-button type="link" @click="cancel" style="width: 364px; height: 40px; color: rgba(0,0,0,0.65);">返回</a-button></div>
</div>
</div>
</div>
<img class="rightBottomImg" src="https://gitee.com/lingxiu5858/assets/raw/master/img_authorize_rightBottom.png" alt="" />
</div>
<div class="authorize-bottom"></div>
</div>
</template>
<script>
import Cookies from "js-cookie";
import {getCurrentUser} from "@/services/authService/login";
import {requestError, requestFail} from "@/utils/request";
export default {
name: "Authorization",
components:{ BkLottie },
data() {
return {
routeQuery: this.$route.query,
userInfo: {}
};
},
created() {
this.getCookies();
},
mounted() {
},
methods: {
getCookies(){
let { accessToken } = this.routeQuery;
console.log("routeQuery", accessToken);
Cookies.set("Authorization", encodeURIComponent(accessToken)); // token
this.toGetCurrentUser();
},
// 获取当前登录用户信息
toGetCurrentUser(){
getCurrentUser().then((res)=>{
let{data} = res;
if(data && data.success){
console.log("当前登录用户信息", data.result);
this.userInfo = data.result;
}else{
requestFail(res, "");
}
}, requestError);
},
confirm(){
location.replace("/");
},
cancel(){
window.open("about:blank", "_self").close();
}
}
};
</script>
<style lang="less" scoped>
.authorize{
margin: 0 auto;
background: #FFFFFF;
height: 100%;
.authorize-top{
width: 1920px;
height: 464px;
position: relative;
border: 1px solid #979797;
.leftTopImg{
width: 249px;
height: 204px;
}
.transparentLogo{
position: absolute;
top: 41px;
width: 130px;
height: 28px;
margin-left: 61px;
}
.rightBottomImg{
position: absolute;
width: 631px;
height: 371px;
right: 0px;
bottom: 0px;
}
.authorize-title{
font-size: 32px;
font-weight: 600;
color: #FFFFFF;
line-height: 45px;
position: absolute;
left: 45%;
top: 25%;
}
.authorize-content{
width: 586px;
height: 620px;
background: #FFFFFF;
box-shadow: 0px 2px 20px 0px rgba(0,0,0,0.1);
border-radius: 8px;
position: absolute;
left: 50%;
top: 115%;
transform: translate(-50%, -50%);
.logo{
margin: 104px 111px 0px 111px;
display: flex;
justify-content: center;
align-items: center;
.leftLogo, .rightLogo{
img{
width: 88px;
height: 88px;
margin-bottom: 8px;
}
.title{
font-size: 14px;
font-weight: 400;
color: rgba(0,0,0,0.85);
line-height: 20px;
text-align: center;
}
}
.animation{
margin: 0px 60px;
}
}
.container{
margin-top: 122px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.authorize-text{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: 41px;
.tips{
font-size: 14px;
font-weight: 400;
color: rgba(0,0,0,0.45);
line-height: 20px;
}
.compName{
font-size: 16px;
font-weight: 600;
color: rgba(0,0,0,0.85);
line-height: 22px;
}
}
}
}
}
.authorize-bottom{
}
}
</style>