
在chrome插件中,我们通常会看到在插件端登录操作会跳转到第三方独立的web去登录,一旦web登录,返回到插件端,一刷新页面,插件就自动登录了。这是如何实现的呢?本文是插件与web端钱包的单点登录的一篇总结笔记,希望在项目中有所帮助。
本文主要会从以下几点思考插件的单点登录
web端与插件如何通信插件与web端如何信息共享内部插件与content通信机制
postMessage
我们知道在web端一个网站与iframe内嵌的另一个网站可以通过postMessage通信,而我们的插件是挂载在content中的,所以我们可以通过postMessage通信吗?
在web端我想过postMessage发送信息给插件
bash
// web
window.postMessage({data: "hello word"}, "*")
在插件端
bash
// chrome plugin content
window.addEventListener("message", (data) => {
console.log(data);
})
由于在插件端排除了插件,所以很显然postMessage与插件的通信基本没有希望。
插件如何与web信息共享
首先我们看一张图,如果插件与web信息共享
插件登录,跳转到web端,web端连接钱包后,插件端刷新就自动登录了。
在web端登录后,插件端刷新页面,插件就自动登录了,后续只要web断链钱包,那么插件端就会断连了。
单点登录最核心是共享cookie
我们先看web端,以伪代码模拟登录
js
// http://localhost:3000
// util.ts
import Cookies from "js-cookie";
export const cookieUtil = {
// 设置cookie
setCookie: (name, value, options) => {
Cookies.set(name, value, options);
},
// 读取cookie
getCookie: name => {
return Cookies.get(name);
},
// 删除cookie
removeCookie: name => {
Cookies.remove(name);
}
};
在App.tsx
js
// http://localhost:3000
// App.tsx
import { cookieUtil } from './util';
const handleLogin = () => {
cookieUtil.setCookie("xToken", "asdtest", {});
}
handleLogin();
在插件端的content中向background发送消息
js
// content.js
chrome.runtime.sendMessage({
type: "getCookie",
});
在backrgound.js中接收这个消息
js
// 在background.js中监听content发送过来的消息,chrome.runtime.onMessage
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const { type } = request;
if (type === "getCookie" && chrome.cookies && chrome.cookies.get) {
chrome.cookies.get(
{ url: "http://localhost:3000/", name: "xToken" },
async (res) => {
const [tab] = await chrome.tabs.query({
active: true,
currentWindow: true,
});
await chrome.tabs.sendMessage(tab.id, { xToken: res.value });
}
);
}
});
我们在background.js中读取了指定web页的cookie,然后通过chrome.tabs.sendMessage(tab_id, {xToken: 'xxx'})发送给了content 在content.js中,我们接收background.js发送过来的消息
js
// content.js
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const {xToken} = request;
console.log(xToken);
if (xToken) {
console.log('登录了')
} else {
console.log('没登录')
}
});
至此你从插件端拿到web端设置的cookie,那么就可以判断只要web端登录了,那么插件端检测到cookie,那么就自动登录了。
在使用插件读取cookie需要注意几点
- 在
content中使用chrome无法获取cookie
js
// error
chrome.cookies.get
- 使用
cookie必须在manifest.json的permissions必须有cookie
js
{
"host_permissions": [
"http://localhost:3000/"
],
"permissions": ["cookies"],
}
总结
-
postMessage无法与插件通信,因为当前插件屏蔽了插件 -
在
web端设置cookie,在插件端的background读取web端的cookie,然后把cookie传送给content,在content中通过获取的cookie判断是否登录 -
插件访问
cookie只能在backgroud.js中访问,无法直接在content.js中访问,只能在background.js发送信息给content.js