在chrome
插件中,我们通常会看到在插件端登录操作会跳转到第三方独立的web
去登录,一旦web
登录,返回到插件端,一刷新页面,插件就自动登录了。这是如何实现的呢?本文是插件
与web
端的单点登录的一篇总结笔记,希望看完在项目中有所帮助。
本文主要会从以下几点思考插件
的单点登录
web
端与插件
如何通信插件
与web
端如何信息共享内部插件
与content
通信机制
postMessage
我们知道在web
端一个网站与iframe
内嵌的另一个网站可以通过postMessage
通信,而我们的插件是挂载在content
中的,所以我们可以通过postMessage
通信吗?
在web
端我想过postMessage
发送信息给插件
代码语言:javascript
复制
// web | |
window.postMessage({data: "hello word"}, "*") |
在插件端
代码语言:javascript
复制
// chrome plugin content | |
window.addEventListener("message", (data) => { | |
console.log(data); | |
}) |
由于在插件
端排除了插件,所以很显然postMessage
与插件的通信基本没有希望。
插件如何与web信息共享
首先我们看一张图,如何插件与web信息共享
插件登录,跳转到web端,web端连接钱包后,插件端刷新就自动登录了。
在web端登录后,插件端刷新页面,插件就自动登录,后续只要web断链钱包,那么插件端就会断连了。
单点登录最核心是共享cookie
我们先看web
端,以伪代码模拟登录
代码语言:javascript
复制
// 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
代码语言:javascript
复制
// http://localhost:3000 | |
// App.tsx | |
import { cookieUtil } from './util'; | |
const handleLogin = () => { | |
cookieUtil.setCookie("xToken", "asdtest", {}); | |
} | |
handleLogin(); |
在插件
端的content
中向background
发送消息
代码语言:javascript
复制
// content.js | |
chrome.runtime.sendMessage({ | |
type: "getCookie", | |
}); |
在backrgound.js
中接收这个消息
代码语言:javascript
复制
// 在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
发送过来的消息
代码语言:javascript
复制
// 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
代码语言:javascript
复制
// error | |
chrome.cookies.get |
- 使用
cookie
必须在manifest.json
的permissions
必须有cookie
代码语言:javascript
复制
{ | |
"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
最后,看完觉得有收获的,点个赞,在看,转发,收藏等于学会,原创不易,欢迎关注Web技术学苑,好好学习,天天向上!