Laravel + Vue.js 的 SPA 專案中進行微信網頁授權的一種姿勢

田勇發表於2017-04-26

相信 Laravel 和 Vue.js 很多人都已經相當熟悉了,在較近版本的 Laravel 中,已經預設支援 Vue 元件化開發,這也順應了眼下基於 API 前後分離以及開發單頁面應用(SPA)的均勢。

專案基本情況

  • Laravel 5.4
  • overtrue/laravel-wechat 包 (內部依賴 overtrue/wechat)
  • vue.js 2.x
  • vue-router (非必須)
  • vue-axios (非必須)

解決步驟

  1. 安裝 laravel-wechat

使用 composer 安裝好 laravel-wechat 包並做好相關配置,具體如下:

  • 在 config\app.php 中的 providers 陣列下加入下面兩行
Overtrue\LaravelWechat\ServiceProvider::class,
Overtrue\LaravelSocialite\ServiceProvider::class,
  • 在 app\Http\Kernel.php 中的 $routeMilleware 下加入
'wechat.oauth' => \Overtrue\LaravelWechat\Middleware\OAuthAuthenticate::class,

其它一些微信公眾號相關的引數配置請參考 EasyWechat 官方文件

  1. 新增路由

在 routes\web.php 中新增一條路由如下:

Route::get('/mobile', 'MobileController@index')->middleware('wechat:oauth');

注意該路由使用了 oauth:wechat 中介軟體,這個中介軟體將實現網頁授權邏輯。

  1. 建立控制器及宣告方法

建立一個控制器 MobileController,並在其中宣告如下方法:

public function index()
{
    // 拿到授權微信使用者資料
    $wechatUser = session('wechat.oauth_user');

    return response()->view('mobile')->cookie('openid', $wechatUser->id ?? null);
}

這一方法將會在 http 響應中帶上一個含有 openid 值的 Cookie,需要注意的是,這個 Cookie 是加密了的,所以不用擔心安全性方面的問題。如果不想加密,可以在 EncryptCookies 中介軟體裡進行配置。

此外,除了直接使用 openid 之外,也可以使用其它值,甚至根據 openid 查到你本地資料庫中的使用者資料,進而在 Cookie 中傳 user_id。具體用法依個人喜好和需求而定。

響應頭中加入 Cookie 也是所有步驟中的關鍵所在,有了這個 Cookie,後續前端頁面向伺服器發起請求時會自動帶上這個 Cookie。

  1. 新增模板以及 Vue 元件,這個可以參照 Laravel 預設的 welcome.blade.php 模板以及 App.vue 元件調整得到。(注意模板文件名,按前面示例,應該改成 mobile.blade.php)

  2. 定義 API 路由及對應的控制器,在前端頁面里根據需要向伺服器發起請求。具體怎麼發就得看用的什麼外掛了,比如我用的 axios,事件就很簡單

axios.get(url).then(response => {
  console.log(response.data)
}).catch(error => {
  console.log(error)
})
  1. 最後,在 API 控制器裡,可以取到當前授權的微信使用者 openid
// 請求頭裡的 openid
$openid = Crypt::decrypt(\Request::cookie('openid'));

這裡使用 Crypt::decrypt() 方法進行解密,如果沒加密,可不使用。

總結

由可可見,在 SPA 專案裡完成網頁授權也十分容易,當然,這也部分歸功於超哥的 laravel-wechat 包。

因為不同於傳統的 Laravel 專案,前後分離的 SPA 專案前後端以 API 作為紐帶,而在這些 API 相關的控制器裡,無法再隨意使用伺服器會話,所以這裡使用 http cookie 作為替代,實際上網頁授權邏輯,在進入 SPA 頁面 Vue 根例項建立之前就已經完成了,算是一種變通吧,至於這個姿勢科學、優雅與否,我也不太好說,但至少目前為止自己的幾個專案中使用一切正常…… :smile:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章