ホームページ  >  記事  >  ウェブフロントエンド  >  Electron は QQ クイック ログインをどのように実装していますか?

Electron は QQ クイック ログインをどのように実装していますか?

不言
不言転載
2018-10-22 14:33:223091ブラウズ

この記事の内容は、Electron が QQ クイック ログインをどのように実現できるかについてです。困っている友人は参考にしていただければ幸いです。

最初はこの関数を書かないつもりだったのですが、お客様が QQ 経由でログインしなければならなかったので、仕方なく書かせていただきました。ちなみに記事を書きました!
書く前に 2 つの質問があります:
1: qq 認証ページを開き、ページ上のリンクをクリックして別のページを開きます。....
2: 認証が成功したかどうかを判断するのは困難です。

しかし、私の頭の中に考えがあります。Electron はブラウザに似ているので、リンクのクリックを確実に防止し、ステータスを判断できます。
ドキュメントを読んでみましょう。

皆さんに、w3c にアクセスしてドキュメントの比較を見ることをお勧めします。完全かつ高速で、ドキュメントは比較的新しいです。

https://electronjs.org/docs ここでの応答速度は比較的遅いです。ドキュメントの多くは非常に古く、パラメーターも無効です。!!!

qq ログインの伝説に戻りましょう!

バックエンドは PHP を使用して実装されていますが、これは難しくありません。主なことはクライアント側での処理です。

qq ログイン ボタンを配置します

#
<template>
    <div>
        <button @click="qqLogin">qq登录</button>
    </div>
</template>

<script>
    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()
            },
        }
    }
</script>

問題解決

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

qq 認証ページを開き、ページ内のリンクをクリックすると、webContents を使用して別のウィンドウが開きます。新しいウィンドウ イベントは、シェルを呼び出して開くデフォルト イベントを編成します。デフォルトのブラウザで実行してください!

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

認証後に成功したかどうかを判断するのは困難です

この問題を見て、応答という言葉を思い出しました。とコードを検索して、webContents で見つけました!
ただし、直接使用することはできず、使用する前に [承認] をクリックする必要があります

     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 イベントの説明:
このイベントは、ユーザーまたはページがナビゲーションを開始したいときに発行されます。このイベントは、window.location オブジェクトが変更されたとき、またはユーザーがページ内のリンクをクリックしたときに発生します。 API (webContents.loadURL や webContents.back など) を使用してプログラムでナビゲーションを開始する場合、イベントは発生しません。
アンカー リンクのクリックやウィンドウの更新など、ページ内でジャンプする場合にもイベントは発生しません。 location.hash。この目的は、did-navigate-in-page イベントを使用して達成できます。

did-get-response-details イベントの説明:

このイベントは、要求されたリソースに関する詳細情報が取得されたときに発行されます。ステータスの識別 リソースをダウンロードするためのソケット リンクを取得します。

これら 2 つを取得したら、コードを記述できます!

[承認] をクリックすると、承認ページがサーバーのコールバック アドレスにジャンプし、実行されます。たとえば、ユーザー トークンの取得は面倒です。その後、生成されたトークンをクライアントに返します。
#ただし、サーバーから返されたデータはクライアントでは解析できないことに注意してください。 findInPage を使用して、返されたコンテンツをクエリします!

しかし、私はそれをしませんでした。


did-get-response-details イベントが次を返したためです:

status、newURL、originalURL、httpResponseCode、requestMethod、referrer、ヘッダー 8 つのパラメーター

結局必要なのは httpResponseCode が 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 トークンはサーバー コードによって生成されるカスタム パラメータです。!

これらを取得するのは簡単です!

レンダリング プロセスはヘッダー内のトークンを取得し、その後は、トークンに基づいてユーザー情報を取得するだけです。!!!

メイン プロセス コード:

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();
            }
        })
    });
});
Notes

返されたヘッダーこの書き方は本当に不正です。header.token[0] を書かなければなりません。この書き方は好きではありませんが、

#

以上がElectron は QQ クイック ログインをどのように実装していますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。