上两篇文章说了,如何在Web端实现Google/Facebook的第三方登录。

这就简单说下 Electron 实现第三方登录。

其实,整个流程中与Web版本最大区别就是,如何获取回调的参数。


Electron 监听回调URL

 1//注册监听事件
 2OAuth.webContents.on('did-navigate', (event, url) => {
 3    let raw_code = /access_token=([^&]*)/.exec(url) || null;
 4    let access_token = (raw_code && raw_code.length > 1) ? raw_code[1] : null;
 5    let raw_state = /state=([^&]*)/.exec(url) || null;
 6    let state = (raw_state && raw_state.length > 1) ? raw_state[1] : null;
 7    let raw_time = /data_access_expiration_time=([^&]*)/.exec(url) || null;
 8    let expiration_time = (raw_time && raw_time.length > 1) ? raw_time[1] : null;
 9    // let error = /\?error=(.+)$/.exec(url);
10
11    //获取到三个参数,即视为登录成功
12    //PS:其实还应该验证回调域名是否匹配
13    if (access_token && state && expiration_time) {
14        //向登录窗体发消息,通知器第三方登录成功,继续走原来的流程
15        AuthUI.webContents.send('oauth.success', {
16            access_token: access_token,
17            state: state,
18            expiration_time: expiration_time,
19            type: 'facebook'
20        });
21        //登录成功后销毁窗体
22        OAuth.destroy();
23    }
24});

Electron 注册全局过滤器

 1//全局过滤器方案
 2let options = {
 3    scopes: 'email',
 4    redirect_uri: 'https://www.facebook.com/connect/login_success.html'
 5};
 6
 7let filter = {
 8	urls: [options.redirect_uri + '*']
 9};
10session.defaultSession.webRequest.onCompleted(filter, (details) => {
11	var url = details.url;
12    let raw_code = /access_token=([^&]*)/.exec(url) || null;
13	let access_token = (raw_code && raw_code.length > 1) ? raw_code[1] : null;
14    let raw_state = /state=([^&]*)/.exec(url) || null;
15	let state = (raw_state && raw_state.length > 1) ? raw_state[1] : null;
16    let raw_time = /data_access_expiration_time=([^&]*)/.exec(url) || null;
17	let data_access_expiration_time = (raw_time && raw_time.length > 1) ? raw_time[1] : null;
18    let error = /\?error=(.+)$/.exec(url);
19
20    //获取到三个参数,即视为登录成功
21	if (access_token && state && data_access_expiration_time) {
22        //向登录窗体发消息,通知器第三方登录成功,继续走原来的流程
23        AuthUI.webContents.send('oauth.success', {
24            access_token:access_token,
25            state:state,
26            data_access_expiration_time:data_access_expiration_time
27        });
28		//登录成功后销毁窗体
29        OAuth.destroy();
30	}
31});

清理Cookie

清理Cookie保证每次弹窗都会提示用户登录,哪怕用户不小心勾选了记住我

 1await new Promise((resolve, reject) => {
 2    session.defaultSession.cookies.get({})
 3        .then((cookies) => {
 4            cookies.forEach(cookie => {
 5                let url = '';
 6                // get prefix, like https://www.
 7                url += cookie.secure ? 'https://' : 'http://';
 8                url += cookie.domain.charAt(0) === '.' ? 'www' : '';
 9                // append domain and path
10                url += cookie.domain;
11                url += cookie.path;
12                session.defaultSession.cookies.remove(url, cookie.name, (error) => {
13                    if (error) console.log(`error removing cookie ${cookie.name}`, error);
14                });
15            })
16            resolve('success')
17        }).catch((error) => {
18            console.log(error)
19            reject('error')
20        })
21})