使用nginx代理支援微信網頁授權不同網域名稱

來源:互聯網
上載者:User
這篇文章主要介紹了關於使用nginx代理支援網頁授權不同網域名稱,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

承認有點標題黨了。這次開發一個項目遇到問題,以前有兩個老項目基於 yaf,網域名稱為 m.baidu.com(做樣本),然後網頁授權網域名稱填的是 m.baidu.com,而這次新開發的項目是基於 laravel,那麼網域名稱為 wechat.baidu.com,但是網頁授權網域名稱怎麼辦,這就坑爹了。當然了,大部分人不會遇到這麼蛋疼的事情吧。

前提

laravel5.5php7.1.0nginx1.10overtrue/laravel-wechat

瞭解OAuth

這個過程必須要明白

感謝超神的圖片

從流程我們可以看到,回調url網域名稱其實就是我們的網頁授權網域名稱。那麼既然這樣我們是不是可以造個假呢,
在網域名稱為wechat.baidu.com的項目下,我們也把網頁授權網域名稱寫成m.baidu.com,然後再使用nginx做代理,基於location 轉寄到wechat.baidu.com下;

改寫overtrue/laravel-wechat中介軟體

為什麼要改寫這個中介軟體呢,因為中介軟體預設會直接擷取你的網域名稱,所以如果我使用 wechat.baidu.com,那麼預設就會回調後跳轉到 wechat.baidu.com,而實際上我要跳轉到 m.baidu.com

Middleware檔案夾下建立一個中介軟體OAuthAuthenticate,並且繼承 Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate;:

namespace App\Http\Middleware;use Illuminate\Http\Request;use Illuminate\Support\Facades\App;use Illuminate\Support\Facades\Event;use Overtrue\LaravelWeChat\Events\WeChatUserAuthorized;use Overtrue\LaravelWeChat\Middleware\OAuthAuthenticate as BaseAuthenticate;class OAuthAuthenticate extends BaseAuthenticate{          public function handle($request, \Closure $next, $account = 'default', $scopes = null)    {        // $account 與 $scopes 寫反的情況        if (is_array($scopes) || (\is_string($account) && str_is('snsapi_*', $account))) {            list($account, $scopes) = [$scopes, $account];            $account || $account = 'default';        }        $isNewSession = false;        $sessionKey = \sprintf('wechat.oauth_user.%s', $account);        $config = config(\sprintf('wechat.official_account.%s', $account), []);        $officialAccount = app(\sprintf('wechat.official_account.%s', $account));        $scopes = $scopes ?: array_get($config, 'oauth.scopes', ['snsapi_base']);        if (is_string($scopes)) {            $scopes = array_map('trim', explode(',', $scopes));        }        $session = session($sessionKey, []);        if (!$session) {            if ($request->has('code')) {                session([$sessionKey => $officialAccount->oauth->user() ?? []]);                $isNewSession = true;                Event::fire(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));                return redirect()->to($this->getTargetUrl($request));            }            session()->forget($sessionKey);            //本地和測試環境下使用這個            if(App::environment()=='local' ||App::environment()=="test"){                return $officialAccount->oauth->scopes($scopes)->redirect($request->fullUrl());            }            $query = $request->getQueryString();            $question = $request->getBaseUrl().$request->getPathInfo() == '/' ? '/?' : '?';            $url= $query ? $request->getPathInfo().$question.$query : $request->getPathInfo();            $url="http://m.baidu.com".$url; //就這一步很重要                        return $officialAccount->oauth->scopes($scopes)->redirect($url);        }        Event::fire(new WeChatUserAuthorized(session($sessionKey), $isNewSession, $account));        return $next($request);    }   }

然後在kernel.php中的$routeMiddleware添加

"wechat.oauth.baidu.com"=>OAuthAuthenticate::class

然後就可以在路由檔案使用了,完工。

nginx 設定代理

這個覺得沒有什麼好講的,其實原理很簡單,直接上代碼
     //在m.baidu.com網域名稱配置下,設定location規則,所有router以/official_account開頭的都去wechat.baidu.com下,然後設定跨域          location /official_account/{        add_header 'Access-Control-Allow-Origin' "$http_origin";        add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-CSRF-TOKEN,X-XSRF-TOKEN';        add_header 'Access-Control-Allow-Credentials' 'true';        if ($request_method = 'OPTIONS') {                add_header 'Access-Control-Allow-Origin' "$http_origin";                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';                add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,X-CSRF-TOKEN,X-XSRF-TOKEN';                add_header 'Access-Control-Allow-Credentials' 'true';                #add_header 'Access-Control-Max-Age' 1728000; # 20 天                #add_header 'Content-Type' 'text/html charset=UTF-8';                #add_header 'Content-Length' 0;                return 200;        }    # 這下面是要被代理的後端伺服器,它們就不需要修改代碼來支援跨域了        proxy_pass http://wechat.m.liaorusanshe.com;        #       proxy_set_header Host $host;          proxy_redirect off;        #proxy_set_header X-Real-IP $remote_addr;         #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_connect_timeout 60;        proxy_read_timeout 60;        proxy_send_timeout 60;    }

這個代碼配置參考了《Nginx配置實現CORS》,但是直接複製過來,配合proxy_pass會出現400 request header or cookie too large錯誤, 百度了一下"400 Bad Request Request Header Or Cookie Too Large",<<nginx配置反向 Proxy或跳轉出現400問題處理記錄>>可以解決,就是如下三個設定有問題,去掉就好了:

         proxy_set_header Host $host;           proxy_set_header X-Real-IP $remote_addr;         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

綜合分析,應該是nginx在使用proxy_pass做跳轉時,如果直接使用網域名稱,且需要向後端提交當前訪問的IP地址時,引發nginxbug造成死迴圈,不知道大家有沒有遇到過這種情況。

然後重新啟動就好了,完工。

以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.