|
掃碼登錄成為一種日趨流行的登錄方式,它具有較高的安全性,同時又使我們從記憶大量的賬號密碼并手動輸入的繁瑣流程中解脫出來,有些平臺甚至無賬號也能掃碼登錄,連注冊的麻煩都省了。 對于接入微信開放平臺的公眾號應用來說,實現(xiàn)掃碼登錄是相當容易的,有 EasyWeChat SDK 加持,再按著官方的文檔一把梭,很快就能完成。 基本思路:
以下就來介紹一下具體實現(xiàn),先放效果圖。 具體實現(xiàn)配合本文,我創(chuàng)建了一個簡單的示例項目,有興趣的可以克隆下來,配合源碼一起服用,效果更佳。項目地址:https://github.com/tianyong90/laravel-qrcode-login
前端監(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)配置
主要是配置數(shù)據(jù)庫和 redis 連接,然后把 BROADCAST_DRIVER 設(shè)置為 redis(這一點很重要,如果使用 pusher 則需要修改為 pusher) 如果 QUEUE_CONNECTION 設(shè)置為 redis 了,則需要記得啟動隊列 worker.
因為使用 laradock,所以只需要啟動時帶上 laravel-echo-server 參數(shù)就可以了,進入 laradock 目錄 docker-compose up -d nginx php-worker nginx mysql redis laravel-echo-server
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ù)中。
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();
}
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 }} />>
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:///, 歡迎各位大佬批評指正。 |
|
|