electronはqqのショートカットのログインを実現します!


この机能を书かないと思っていたのに、お客様はqq登录を必死にしました.仕方なく書きましたので、ついでに文章を書きます!书く前に2つの问题があります:1:qq授権ページを开いてページの中のリンクをクリックしてまた1つのページを开きます!.....2:承認後に成功するかどうかは判断しにくい
しかし、electronはブラウザのようなもので、ブラウザである以上、リンクのクリックを阻止したり、状態を判断したりすることができるという考えが頭に浮かんでいます.ドキュメントをかじりに行きます!!!
w 3 cに行ってドキュメントを見ることをお勧めします.また、ドキュメントも比較的速いので、新しいものを見ることができます.https://www.w3cschool.cn/elec...
https://electronjs.org/docsこの中の応答速度は比較的に遅くて、中の多くのドキュメントはすべて長い間パラメータも失効しました!!!
本題に戻ってqq登録を言います!
バックエンドはPHPで実現するのは難しくありません.主なのはクライアントの処理です.

デモ


qqログインボタンを置く




    export default {
        name: "home",
        mounted() {
            this.$electron.ipcRenderer.on('reply', (e, data) => {
                console.log(data)
                let httpCode = data.request_code[0];
                if (httpCode === '1') {
                    alert(data.token[0])
                }
            })
        },
        methods: {
            qqLogin() {
            //              
                this.$http.get('xxxxx')
                    .then((result) => {
                        if (result.data.status === 1) {
                            this.$electron.ipcRenderer.send('qqLogin', {url: result.data.data});
                        }
                    })
                    .catch()
            },
        }
    }

問題解決


aリンクをクリックすると新しいウィンドウが開きます


qq授権ページを开けてページの中のリンクをクリックしてまた1つのウィンドウを开く问题を解决してwebContentsのnew-windowイベント组织のデフォルトのイベント呼び出しShellを使ってデフォルトのブラウザで开けばいいです!
   loginWindow.webContents.on('new-window', (event, url) => {
        event.preventDefault();
        shell.openExternal(url);
    });

授権後に成功するかどうかは判断しにくい。


この問題に着いたら、Responseとcodeという言葉を思い出して検索しましたか?結局webContentsで見つけました!did-get-redirect-request事件!しかし、私たちは彼を直接使用することはできません.彼は許可をクリックしてから彼を使用します.
     loginWindow.webContents.on('will-navigate', (e, url,) => {
        content.on('did-get-response-details', (e, status, url, originalURL, httpResponseCode, requestMethod, referrer, header) => {
            if (httpResponseCode === 200) {
                event.sender.send('reply', header);
                // loginWindow.close();
            }
        })
    });

will-navigateイベント解釈:ユーザまたはpageがナビゲーションを開始しようとするとイベントが発行される.Windowsになりますlocationオブジェクトが変更されたり、ユーザがpageのリンクをクリックするときに発生する.このイベントは、api(webContents.loadURLやwebContents.backなど)を使用してプログラミングでナビゲーションを開始すると発行されません.アンカーリンクをクリックしたりwindowを更新したりするなど、ページ内でジャンプすることはありません.location.hash.did-navigate-in-pageイベントを使用して目的を達成
did-get-response-detailsイベント解釈:リクエストリソースの詳細が利用可能である場合にイベントを発行する.statusはsocketリンクを識別してリソースをダウンロードする.
この2つを手に入れたらコードを書くことができます!ライセンスをクリックすると、ライセンスページが私たちのサーバのコールバックアドレスにジャンプし、ユーザーtokenを取得するなどの操作を行います.その後、生成されたtokenがクライアントに返されます!
しかし、ここでサービス側が返すデータクライアントが解析できないことに注意してください.findInPageを使用して、返す内容を検索することができます.でも私はそうしなかったdid-get-response-detailsイベントは、statusnewURLoriginalURLhttpResponseCoderequestMethodreferrerheadershttpResponseCodeの8つのパラメータが返されたため、最終的にはheaderが200であると判断する必要があります.
access-control-allow-credentials:["true"]
access-control-allow-headers:["token,Origin, X-Requested-With, Content-Type, Accept"]
access-control-allow-methods:["POST,GET,DELETE,PUT"]
cache-control:["no-store, no-cache, must-revalidate"]
connection:["Keep-Alive"]
content-type:["application/json; charset=utf-8"]
date:["Sun, 21 Oct 2018 14:02:20 GMT"]
expires:["Thu, 19 Nov 1981 08:52:00 GMT"]
keep-alive:["timeout=5, max=100"]
request_code:["1"]
msg:["    "]
token:["xxxxxxxx"]
pragma:["no-cache"]
server:["Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9"]
set-cookie:["PHPSESSID=6b0esq5jd8vloess2c96ove86s; path=/; HttpOnly"]
transfer-encoding:["chunked"]
x-powered-by:["PHP/7.2.1"]

以上のパラメータのうちmsg request_code tokenはカスタムパラメータでサーバコード生成です!
これを手に入れられると助かります!
レンダープロセスはheadertokenを手に入れてtokenに基づいてユーザー情報を取得してから簡単です!!!

メインプロセスコード:

import {ipcMain, BrowserWindow, shell} from 'electron'

ipcMain.on('qqLogin', (event, data) => {
    const loginWindow = new BrowserWindow({
        width: 750,
        height: 450,
        resizable: false,
        minimizable: false,
        maximizable: false,
        webPreferences: {
            devTools: false,
        }
    });

    loginWindow.setMenu(null);

    loginWindow.loadURL(data.url);
    
    loginWindow.webContents.on('new-window', (event, url) => {
        event.preventDefault();
        shell.openExternal(url);
    });
    const content = loginWindow.webContents;

    content.on('will-navigate', (e, status, url,) => {
        content.on('did-get-response-details', (e, status, url, originalURL, httpResponseCode, requestMethod, referrer, header) => {
            if (httpResponseCode === 200) {
                event.sender.send('reply', header);
                loginWindow.close();
            }
        })
    });
});

注意点


戻ってきたヘッドの中には配列があるという書き方は本当にお父さんですね.またheader.token[0]という書き方を書くのはちょっと嫌ですが仕方がありません!