Routing doesn't work properly when URL clicked

2019-08-04 11:09发布

问题:

We have an application running on PHP 5.5 & Laravel 5.2. It has a user account area, in which all routes are prefixed by /account/. The default route for the account area is /account/services. Users are routed to this page by default after login.

Of course, if a user enters a specific account area URL such as example.com/account/billing, they are taken to the billing page upon login (or directly, if already authenticated).

However, if I click https://example.com/billing in Excel or Word, I go to the default /account/services page (if authenticated; otherwise I go there after logging in).

At first I believed this was because they are inserting hidden character(s) and thus invalidating the URL, causing our application to route the user to the default URL.

So I tried these solutions:

  • trim() the URL
  • Removing nonbreaking spaces: $url = preg_replace('~\x{00a0}~','',$reqURL);
  • function to remove byte order mark (sourced here)

I've even copied test URLs from the browser into NPP and viewed as hex. There don't appear to be any extra characters.

If I manually type the same URL into the browser bar, everything works perfectly.

This is only happening for URLs which require authentication, public / frontend URLs seem unaffected. This lead me to this answer, but I'm not sure it applies in our case. Microsoft is indeed running Microsoft Office Protocol Discovery before opening these URLs in the browser, but our authentication cookie is being recognized (the browser opens to the login page, but immediately redirects to the account area if the user has a valid cookie).

Has anyone else experienced this? And what other causes could I look at?

回答1:

Microsoft's user agent was indeed the culprit.

I solved it with an .htaccess rule which returns a 200 response to requests from Office-related user agents. (Previously, Laravel was returning a 302 redirect to the login page, since these routes require authentication.) This tricks Office into opening a browser with the intended URL (if they aren't authenticated, they're still redirected to the login form, but post-login redirect now works perfectly).

# Return 200 to Microsoft Office user agents to resolve redirection issue
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} MSOffice [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Microsoft\ Office\ Word [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Office [NC,OR]
RewriteCond %{HTTP_USER_AGENT} Microsoft\ Office\ PowerPoint [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ms\-office [NC]
RewriteRule .* - [R=200,L]

I also tried this rule, which returns a "Method Not Allowed" response to the MS Office Protocol user agent, but it didn't solve the issue.

# Intercept Microsoft Office Protocol Discovery
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteCond %{HTTP_USER_AGENT} ^Microsoft\ Office\ Protocol\ Discovery [OR]
RewriteCond %{HTTP_USER_AGENT} ^Microsoft\ Office\ Existence\ Discovery [OR]
RewriteCond %{HTTP_USER_AGENT} ^Microsoft\-WebDAV\-MiniRedir.*$
RewriteRule .* - [R=405,L]


标签: php laravel-5