1:单点登录实现效果
1:我这里的项目是内嵌到其他项目里的,可以说我这是子项目,
2:父项目打开一个菜单导航,页面内容为内嵌iframe
3:此时子项目显示在iframe中,并且免除登录步骤,直接进入首页显示数据
2:实现流程
1:父项目通过iframe给我们传递一个标识,
2:我们在登录页面判断此标识,在成功的回调里单独编写一份登录的方法
(如果调用点击按钮登录的方法,会报错 cancelToken of undefined : 请求取消),
3:存储token,跳转到首页。此时的效果就是父项目打开他的导航菜单就直接通过iframe显示内嵌项目的首页,
3:子项目代码
重点:单点登录的代码不能写在 export default 对象内
<script>
import { validUsername } from "@/utils/validate";
import axios from "axios";
import router from "@/router";
import { Message } from "element-ui";
注释:父项目传来的标识是window.name,这里我是直接判断window.name
if (window.name == "iframeID1") {
注释:这里这里我们要后台写一个获取密码的接口,这样我们在单点登录后修改密码,也能随时取用最新的密码继续来进行单点登录
axios({
url: "/v1/get/pwd",
method: "post",
headers: {
"content-type": "application/json",
},
}).then((res) => {
注释:获取密码后,把密码传递给登录接口的密码字段
axios({
url: "/v1/user/login",
method: "post",
data: {
name: "admin",
pwd: res.data.pwd,
},
json: true,
headers: {
"content-type": "application/json",
},
}).then((res) => {
if (res.data.resultState == "success") {
注释:判断登录成功后,我这里是吧token存到了本地,并且跳转页面
sessionStorage.setItem("pwdtoken", res.headers.pwdtoken);
router.push(`/`);
} else if (
res.data.resultState == "fail" &&
res.data.resultMsg == "pwd error!"
) {
Message({
message: "密码错误",
type: "error",
});
} else {
Message({
message: "登录出错",
type: "error",
});
}
});
});
}
export default {......}
4:父项目代码
父代码只是为了给子项目传递一个标识,所以这里我直接贴图片
5:单点登录常见问题
单点登录实现的过程也挺艰难的,毕竟从未接触过这种需求,也没有人可以求助,所以就自己不断摸索。
从开始到结束其实也没什么问题,主要的问题就是不知道怎么实现,一头雾水的问题。
当实现后其实也挺简单的。上面的代码也并不难,不算多,但能把问题给解决了。
这些代码都是好几天摸索出来的,我下面就说说我遇到过的问题
1:最开始是父项目内创建了子项目的axios,也在父项目内写了子项目的登录功能,但问题是ip不能改变
2:也是跟在第一个问题上,因为子项目的token是本地存储(sessionStorage)的,所以父项目写了子项目的登录功能也进行了token存储,
自然也只是存到了父项目ip上,本地的子项目ip还是需要在内嵌的页面中点击子项目的登录按钮,
走子项目的登录功能,才能把token存到子项目的ip上,但是单点登录就是为了取消这一步骤才存在的。
中间也想了本地存储的setitem能不能改变ip存储,自然也是不可能的
3:这个时候也已经借助了百度中搜索的其中一个方法,用iframe传递标识给子项目,子项目靠这个标识来编写代码。这个时候问题也卡在了token上,也就是第二步token存储的问题
然后就把本地存储改成了vuex也就是在这个时候遇到了"cancelToken" of undefined的问题,我们在下一个目录来细说。
4:最后把"cancelToken" of undefined的问题彻底解决后发现还是不行。我就直接单独在判断标识的地方又写了一个登录的api方法,
然后也就从这一步开始才找到了突破点,最后一点点调试修改才完成
5:因为是两个人一起商量着来的,但是另一个同事居家,沟通也不方便,整体来说有点难,但解决了,也挺不错的。
6:“cancelToken” of undefined请求异常
这个错误图片说明了我们请求正常也不正常。请求是请求了,但是我写的log响应却没有打印,
请求之后就报错了,说明我们请求被终止了,没有响应
其实这个错百度一搜都能出来,几个网页打开都是同样的答案,但是也都不能解决问题。
其实这个问题的原因是请求被取消了
我有两次这种情况
1:我把登录api方法写在的vuex的actions里,点击登录按钮调用vuex的方法,
这里是第一次出现"cancelToken" of undefined,我这样写是为了把token存到vuex里。
后来我把登录api的方法写在了登录页的登录按钮点击方法上,
然后在成功回调里再调用vuex的actions方法,此时vuex的方法只有存储token的功能,
"cancelToken" of undefined的错误被解决了。
2:我在实现单点登录时判断的window.name后,没有另外写登录api方法,而是用了一些手法,
把登录方法和账号密码挂载到了window上。
此时通过window调用登录方法也报错"cancelToken" of undefined,同样请求被取消。
最后我把调用的方法改成了用axios单独重写一个登录api方法,这才没有报错
3:总结:
"cancelToken" of undefined的报错并不单单是因为拦截器里没有return config
当直接调用封装的需要有操作才能执行的方法时,也会报这个错。
这时我们就要知道我们应该再重写一个api方法,不要再为了省事去直接调用了
结束!
无效:https://github.com/webrtc/samples/tree/master/src/content/peerconnection/multiple