1. 程式人生 > >Chrome外掛:微信公眾號自動登入(chrome.extension)

Chrome外掛:微信公眾號自動登入(chrome.extension)

manifest.json:

{
    "manifest_version": 2,
    "name": "WX.AutoLogin",
    "version": "1.0.0",
    "description": "微信公眾號自動登入系統",
    "icons": {
        "16": "img/icon.png",
        "48": "img/icon.png",
        "128": "img/icon.png"
    },
    "browser_action": {
        "default_icon": "img/icon.png",
        
"default_title": "微信公眾號自動登入系統", "default_popup": "popup.html" }, "permissions": [ "cookies", "storage", "tabs", "*://mp.weixin.qq.com/*" ], "background": { "scripts": ["js/background.js"] }, "content_scripts": [{ "matches": ["*://mp.weixin.qq.com/*"],
// 多個JS按順序注入 "js": ["js/jquery-1.8.3.js", "js/content-script.js"], // 程式碼注入的時間,可選值: "document_start", "document_end", or "document_idle",最後一個表示頁面空閒時,預設document_idle "run_at": "document_start" }] }

popup.js:

function msg(msg) {
    layer.msg(msg, {offset: 0, shift:6});
}

$(document).ready(
function(){ chrome.storage.local.get(null, function (items) { console.log('items:', items); for (var key in items) { if (key == '__names') { continue; } $('#accountBtnArea').append('\ <div class="button-row" data-user="'+items[key].user+'">\ <button class="account-btn">&nbsp;'+items[key].name+'</button>\ <div class="icon-container delete-acct"><i class="fa fa-trash"></i></div>\ </div>'); } }); $('#showAddBtn').click(function(event) { $('.button-area').hide(); $('.add-area').show(); $('.acct-input').val(''); }); $('#cancelBtn').click(function(event) { $('.button-area').show(); $('.add-area').hide(); }); $('#confirmBtn').click(function(event) { var name = $('#accountName').val(); var user = $('#account').val(); var pwd = $('#password').val(); if (!name || !user || !pwd) { msg('請填入資訊!'); return; } if (name == '__names') { msg('該名字不允許使用!'); return; } chrome.storage.local.get([user, '__names'], function(result) { if (result[user]) { msg('該使用者已存在,請刪除後再新增'); return; } if (result.__names && result.__names[name]) { msg('您已經有該名字了,請換個名字吧!'); return; } if (!result.__names) { result.__names = {}; } $('#accountBtnArea').append('\ <div class="button-row" data-user="'+user+'">\ <button class="account-btn">'+name+'</button>\ <div class="icon-container delete-acct"><i class="fa fa-trash"></i></div>\ </div>'); $('.button-area').show(); $('.add-area').hide(); var saveObj = {}; saveObj[user] = { user: user, pwd: md5(pwd), name: name } result.__names[name] = ''; saveObj['__names'] = result.__names; chrome.storage.local.set(saveObj); }); }); $('body').on('click', '.delete-acct', function(event) { $(this).closest('.button-row').remove(); var user = $(this).closest('.button-row').attr('data-user'); chrome.storage.local.remove(user); chrome.storage.local.get([user, '__names'], function(result) { delete result.__names[user]; chrome.storage.local.set({__names: result.__names}); }); }); $('body').on('click', '.button-row', function(event) { var bg = chrome.extension.getBackgroundPage(); bg.start($(this).data('user')); }); });

background.js:

var userStor;

function removeAllCookies(cookies) {
    cookies.forEach(function(cookie, index) {
        chrome.cookies.remove({
            'url':'https://mp.weixin.qq.com',
            'name': cookie.name
        });
    })
}

function start(user) {    
    chrome.storage.local.get([user], function(result) {
        if (result && result[user] && result[user].user && result[user].pwd) {
            userStor = result[user];
            var time = Date.now()/1000|0;
            if (!userStor.cookies || time >= userStor.expire_time) { // 超時,需重新登陸
                chrome.cookies.getAll({url: 'https://mp.weixin.qq.com/'}, function (cookies) {
                    removeAllCookies(cookies);
                    chrome.tabs.create({'url': 'https://mp.weixin.qq.com/#login'});
                });
                return;
            }
            // 沒有超時,直接設定cookie登陸
            chrome.cookies.getAll({url: 'https://mp.weixin.qq.com/'}, function (cookies) {
                removeAllCookies(cookies);
                userStor.cookies.forEach(function(cookie, index) {
                    delete cookie.hostOnly;
                    delete cookie.session;
                    cookie.url = 'https://mp.weixin.qq.com/';
                    chrome.cookies.set(cookie);
                });
                // console.log('成功登陸公眾號,準備跳轉...')
                // chrome.tabs.create({'url': 'https://mp.weixin.qq.com/'});
                chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
                    if (tabs[0].url.startsWith('https://mp.weixin.qq.com') && tabs[0].id) { // 該頁面直接跳轉
                        chrome.tabs.sendMessage(tabs[0].id, {cmd:'jump_url', url:'https://mp.weixin.qq.com/'});
                    } else {
                        chrome.tabs.create({'url': 'https://mp.weixin.qq.com/'});
                    }
                });
        });
        } else {
            console.log('請先新增賬號!');
        }
    });
}

// 監聽來自content-script的訊息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {    
    if (request.type == 'login_success') {
        chrome.cookies.getAll({url: 'https://mp.weixin.qq.com/'}, function (cookies) {
            userStor.token = request.token;
            userStor.cookies = cookies;
            var time = Date.now()/1000|0;
            userStor.expire_time = time + 12*3600 - 60;
            var saveObj = {};
            saveObj[request.user] = userStor;
            chrome.storage.local.set(saveObj);            
            chrome.tabs.sendMessage(request.tabId, {cmd:'jump_url', url:'https://mp.weixin.qq.com/'});
        });
    } else if (request.type == 'content_js_start') {        
        if ('https://mp.weixin.qq.com/#login' == request.url) { // 建立重新登入頁面返回的訊息
            chrome.tabs.sendMessage(sender.tab['id'], {cmd:'show_qrcode', user:userStor.user, pwd:userStor.pwd, tabId: sender.tab['id']});
        }
    }
});

content-script.js:

function loginWx(user, tabId) {
    var url = 'https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1';
    (function wxAsk() {
        $.get(url, function(data, status, xhr) {
            if (data.ret) {
                console.log(data)
                return;
            }
            switch (data.status) {
                case 1:
                    if (1 == data.user_category) {
                        url = "https://mp.weixin.qq.com/cgi-bin/loginauth?action=ask&token=&lang=zh_CN&f=json&ajax=1";
                    } else {
                        $.post('https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login&lang=zh_CN', {
                            userlang: 'zh_CN',
                            token: '',
                            lang: 'zh_CN',
                            f: 'json',
                            ajax: '1',
                        }, function(data, textStatus, xhr) {
                            if (data.base_resp && !data.base_resp.ret) {
                                $('#__gzh-saomiao-status').text('登入成功!');
                                var token = data.redirect_url.replace(/.*token=/g, '');
                                chrome.runtime.sendMessage({type: 'login_success', token: token, user: user, tabId: tabId});
                            }
                        });
                        return;
                    }
                    break;
                case 2: $('#__gzh-saomiao-status').text('管理員拒絕!'); return;
                case 3: $('#__gzh-saomiao-status').text('登入超時!'); return;
                case 4: $('#__gzh-saomiao-status').text('掃描成功,等待確認...'); break;
                default: $('#__gzh-saomiao-status').text('等待掃描...'); break;
            }
            setTimeout(function() { wxAsk(); }, 1000);
        });
    })();
}

function start(user, pwd, tabId) {
    $.post('https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin', {
        username: user,
        pwd: pwd,
        imgcode: '',
        f: 'json',
        userlang: 'zh_CN',
        token: '',
        lang: 'zh_CN',
        ajax: '1'
    }, function(data, status, xhr) {
        if (!data || !data.base_resp || data.base_resp.ret) {
            alert('使用者名稱或密碼錯誤!');
            console.log(data);
            return;
        }
        $('body').append('\
            <script>loginWx("'+user+'", '+tabId+');</script>\
            <div style="width: 100%; text-align: center; position: absolute; top: 20%; background: none; z-index: 999; ">\
                <div style="width: 20%; text-align: center; background: #389a20a3; padding: 31px; margin: 0 auto;">\
                    <h1 style="color: #e4f31f;">請掃描二維碼</h1><br>\
                    <img src="https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=getqrcode&param=4300&rd='+Math.floor(1e3 * Math.random())+'" style="width:100%;">\
                    <br><br><h1 id="__gzh-saomiao-status" style="color: #e4f31f;">等待掃描...</h1>\
                </div>\
            </div>\
            <div style="position: fixed; top: 0; right: 0; bottom: 0; left: 0; background-color: rgba(0,0,0,.8); "></div>\
        ');
    });
}

// 監聽來自background-script的訊息
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    // console.log(['get msg from background', request]);
    if(request.cmd == 'show_qrcode') {
        // sendResponse('content js has get msg');
        start(request.user, request.pwd, request.tabId);
    } else if (request.cmd == 'jump_url') {
        window.location.href = request.url;
    }
});

// 傳送訊息給background js
chrome.runtime.sendMessage({type: 'content_js_start', url: window.location.href});