电竞比分网-中国电竞赛事及体育赛事平台

分享

Laravel + Laravel

 中間件 2021-08-16

掃碼登錄成為一種日趨流行的登錄方式,它具有較高的安全性,同時又使我們從記憶大量的賬號密碼并手動輸入的繁瑣流程中解脫出來,有些平臺甚至無賬號也能掃碼登錄,連注冊的麻煩都省了。

對于接入微信開放平臺的公眾號應用來說,實現(xiàn)掃碼登錄是相當容易的,有 EasyWeChat SDK 加持,再按著官方的文檔一把梭,很快就能完成。
然而本文所要討論的是另一種情況,有時候出于某些原因,自己的公眾號不能接入開放平臺,但又想進行微信掃碼登錄,這種情況下顯示就不能再換官方的套路來了。但只要我們稍作變通,就能實現(xiàn)這一需求。

基本思路:

  1. 登錄頁顯示微信二維碼(使用 EasyWeChat SDK 創(chuàng)建,短時效的臨時二維碼)

  2. 用戶掃碼后推送消息到服務器接口,接口中根據(jù)業(yè)務情況進行判斷處理,符合條件時觸發(fā) WechatScanLogin 事件

  3. WechatScanLogin 事件實現(xiàn) ShouldBroadcast 接口,所以當它被觸發(fā)時也會向指定的頻道進行廣播

  4. 前端 laravel-echo 監(jiān)聽頻道中用戶掃碼登錄的消息并進行處理

以下就來介紹一下具體實現(xiàn),先放效果圖。

screenshot

具體實現(xiàn)

配合本文,我創(chuàng)建了一個簡單的示例項目,有興趣的可以克隆下來,配合源碼一起服用,效果更佳。項目地址:https://github.com/tianyong90/laravel-qrcode-login
  1. 首先當然是創(chuàng)建 Laravel 項目,同時安裝前后端依賴

  • 前端最主要依賴是 laravel-echosocket.io-client

前端監(jiān)聽事件廣播是關(guān)鍵,我們需要一個 websocket 服務端,Laravel 官方文檔在介紹消息廣播時提到了 Pusher 和 laravel-echo-server。因為我使用 laradock 作為開發(fā)環(huán)境,其中內(nèi)置了 laravel-echo-server 容器,十分方便,所以決定直接用它。實際上也可以使用 Pusher 服務,那么則需要安裝 pusher.js 替代 socket.io-client,同時在 .env 中修改相關(guān)配置
  1. 配置項目

主要是配置數(shù)據(jù)庫和 redis 連接,然后把 BROADCAST_DRIVER 設(shè)置為 redis(這一點很重要,如果使用 pusher 則需要修改為 pusher)

如果 QUEUE_CONNECTION 設(shè)置為 redis 了,則需要記得啟動隊列 worker.

  1. 啟動 laravel-echo-server

因為使用 laradock,所以只需要啟動時帶上 laravel-echo-server 參數(shù)就可以了,進入 laradock 目錄

docker-compose up -d nginx php-worker nginx mysql redis laravel-echo-server
  1. 創(chuàng)建 WechatScanLogin 事件

php artisan make:event WechatScanLogin
class WechatScanLogin implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $token;

    /**
     * Create a new event instance.
     *
     * @param $token
     */
    public function __construct($token)
    {
        $this->token = $token;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('scan-login’);
    }
}
上面最關(guān)鍵的就是事件要實現(xiàn) ShouldBroadcast 接口并在 broadcastOn 方法中指定要廣播的頻道。WechatScanLogin 的公開屬性 token 會自動包含在廣播數(shù)據(jù)中。
  1. 對接微信消息服務器

laravel-wechat 的相關(guān)配置和對接,請閱讀 EasyWeChat SDK 官方文檔。

接收掃碼的消息并進行相關(guān)處理。

public function serve()
{
    $app = app('wechat.official_account');

    $app->server->push(function ($message) {
        if ($message['Event'] === 'SCAN') {
            $openid = $message['FromUserName'];

            $user = User::where('openid', $openid)->first();

            if ($user) {
                // TODO: 這里根據(jù)情況加入其它鑒權(quán)邏輯

                // 使用 laravel-passport 的個人訪問令牌
                $token = $user->createToken($user->name)->accessToken;

                // 廣播掃碼登錄的消息,以便前端處理
                event(new WechatScanLogin($token));

                \Log::info('haha login');
                return '登錄成功!';
            }

            return '失敗鳥';
        } else {
            // TODO: 用戶不存在時,可以直接回返登錄失敗,也可以創(chuàng)建新的用戶并登錄該用戶再返回
            return '登錄失敗';
        }
    }, \EasyWeChat\Kernel\Messages\Message::EVENT);

    return $app->server->serve();
}
  1. 使用 EasyWeChat 創(chuàng)建臨時二維碼并在頁面中顯示。

public function index()
{
    $wechat = app('wechat.official_account');

    $result = $wechat->qrcode->temporary('foo', 600);
    $qrcodeUrl = $wechat->qrcode->url($result['ticket']);

    return view('index', compact('qrcodeUrl'));
}
<img src={{ qrcodeUrl }} />>
  1. 前端使用 laravel-echo 訂閱對應的微信掃碼登錄事件,接收其中的 token 并存入本地存儲作為判斷是否登錄的憑據(jù),同時這個 token 也將作為訪問后端 api 的授權(quán)依據(jù)。注意前面的代碼中,使用了 laravel-passport 生成這個個人訪問令牌,如果不了解這部分原理,請查閱 Laravel 官方文檔。

import Echo from 'laravel-echo'
import io from 'socket.io-client'

window.io = io

let EchoInstance = new Echo({
  broadcaster: 'socket.io',
  host: window.location.hostname + ':6001',
})

EchoInstance.channel('scan-login').listen('WechatScanLogin', e => {
    localStorage.setItem('my_token', this.token)

    // 其它處理
  })

總結(jié)

至此,簡單的掃碼登錄就完成了。當然,本文示例代碼不怎么優(yōu)雅、流程可能也有不完善的地方,主要是為了提供一個大致思路。有了這個思路,我們可以實現(xiàn)其它諸如掃碼簽到、掃碼投票等各種功能,具體如何就看大家的創(chuàng)意了。

最后放上個人博客地址:https:///, 歡迎各位大佬批評指正。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多