Laravel+easywechat 多公眾號管理

她來聽我的演唱會發表於2020-05-08

開發工作當中,會有這樣的需求:

  1. 一個後臺需要管理多賬號,其中包括多個小程式,多個開放平臺和多個公眾號;
  2. 小程式比較好管理,因為小程式的登入方式是根據小程式的配置資訊(app_id和secret)使用者code獲取open_id、session_key,然後使用session_key、iv、encryptedData獲取基本資訊。因此可以通過不同專案的標識獲取不同的配置;
  3. 公眾號獲取使用者資訊的方式有兩種,一種是使用配置伺服器的方式,但是在ouath域名的配置的時候,無法靈活的配置域名引數,因此放棄;想到使用中介軟體中獲取使用者資訊的方法:
    //中介軟體
    $router->any('/wechat/login', 'WeChatController@login')->middleware(['wechat.oauth','web']);
    //獲取使用者資訊
    $user = session('wechat.oauth_user.default'); 
    那可不可以在wechat.oauth_user.default中下功夫呢?

嘗試:

  1. 在config/wechat.php中增加另外的配置:

    'test' => [
             'app_id' => env('WECHAT_OFFICIAL_ACCOUNT_APPID', ''),         // AppID
             'secret' => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', ''),    // AppSecret
             'token' => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', 'your-token'),           // Token
             'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', ''),                 // EncodingAESKey
    
             /*
              * OAuth 配置
              *
              * scopes:公眾平臺(snsapi_userinfo / snsapi_base),開放平臺:snsapi_login
              * callback:OAuth授權完成後的回撥頁地址(如果使用中介軟體,則隨便填寫。。。)
              */
             'oauth' => [
                 'scopes'   => array_map('trim', explode(',', env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_SCOPES', 'snsapi_userinfo'))),
                 'callback' => env('WECHAT_OFFICIAL_ACCOUNT_OAUTH_CALLBACK', '/login'),
             ],
         ],
  2. 通過easywechat在github中使用中介軟體的說明

    中介軟體支援指定配置名稱:’wechat.oauth:default’,當然,你也可以在中介軟體引數指定當前的 scopes:中介軟體支援指定配置名稱:’wechat.oauth:default’,當然,你也可以在中介軟體引數指定當前的 scopes:

    Route::group(['middleware' => ['wechat.oauth:snsapi_userinfo']], function () {
    // ...
    });
    // 或者指定賬戶的同時指定 scopes:
    Route::group(['middleware' => ['wechat.oauth:default,snsapi_userinfo']], function () {
    // ...
    });
  3. 嘗試在中介軟體中使用中介軟體為:

    [‘middleware’ => [‘wechat.oauth:test,snsapi_userinfo’]

如果這步成功,可以根據傳入引數不同,判斷使用default還是test配置。但是在開發者工具中,喚起授權的依然是default的資訊。
4.所以,檢視了wechat.oauth中介軟體:

//\Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate::class
class OAuthAuthenticate
{
    /**
 * Handle an incoming request. * * @param \Illuminate\Http\Request $request
  * @param \Closure $next
  * @param string|null $scope
  * @param string|null $type : service(服務號), subscription(訂閱號), work(企業微信)
 * * @return mixed */  
 public function handle($request, Closure $next, $account = 'default', $scope = null, $type = 'service')
    {

    }

可以看到,$account預設就是default,因為無論怎麼改都沒辦法進行配置資訊的切換(只討論公眾號)。因此,那可不可以通過路由傳參,中介軟體獲取引數,通過獲取的引數不同,切換不同的配置引數。
路由:

$router->get('/wechat/login/{project?}', 'WeChatController@login')
->middleware(['web','all_wechact_oauth']);

自定義中介軟體:

public function handle($request, Closure $next, $account = 'default', $scope = null, $type = 'service')
    {
        //暫時不做任何判斷,可根據自己需求進行操作
        $isNewSession = false;
        $project_id = $request->project;
        $config = WechatConfig::where('project_id',$project_id)->first();
        $official_account = $config->officialAccount;
        //保證相容性
        $class = ('work' !== $type) ? 'wechat' : 'work';
        $prefix = ('work' !== $type) ? 'official_account' : 'work';
        switch ($official_account->id){
            case 1:
                $account = 'default';
                break;
            case 2:
                $account = 'test';
                break;
        }
        $sessionKey = \sprintf($class.'.oauth_user.%s', $account);
        $config = config(\sprintf('wechat.'.$prefix.'.%s', $account), []);
        $officialAccount = app(\sprintf('wechat.'.$prefix.'.%s', $account));
        $scope = $scope ?: Arr::get($config, 'oauth.scopes', ['snsapi_base']);

        if (is_string($scope)) {
            $scope = array_map('trim', explode(',', $scope));
        }

        $session = session($sessionKey, []);

        if (!$session) {
            if ($request->has('code')) {
                session([$sessionKey => $officialAccount->oauth->user() ?? []]);
                $isNewSession = true;

                event(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));

                return redirect()->to($this->getTargetUrl($request));
            }

            session()->forget($sessionKey);

            return $officialAccount->oauth->scopes($scope)->redirect($request->fullUrl());
        }

        event(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));

        return $next($request);
    }

然後測試,根據傳入不同的project,可以自由切換不同的配置。
暫時想到這一步,後續有其他想法再進行更新!
參考:

  1. Laravel 使用 EasyWechat 管理多公眾號
  2. EasyWechat在laravel中的使用
  3. 文件——路由引數
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章