API Platform JWT认证后请求返回401(JWT未找到)问题排查求助
Hey Alex, I’ve dealt with this exact frustrating issue before—since your setup works locally but breaks on the production server, the problem almost always boils down to server configuration intercepting or dropping the Authorization header. Let’s walk through the most likely fixes step by step:
1. Fix Apache’s Authorization Header Handling (Most Common Culprit)
Apache often strips the Authorization header by default when running PHP via CGI/FastCGI. Here’s how to fix it:
- Check your
.htaccessfile (in your project’spublicdirectory) and add this line if it’s missing:
This ensures the Authorization header gets passed through to PHP.RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] - Verify Apache directory configuration: Make sure your server’s Apache site config has
AllowOverride Allset for your project’s root directory. Without this,.htaccessrules won’t apply. Example:<Directory /var/www/your-project/public> AllowOverride All Require all granted </Directory> - Restart Apache after making changes:
sudo systemctl restart apache2
2. Check File Permissions for JWT Keys
Even if you regenerated the .pem files, the production server might have strict permissions that prevent PHP from reading them:
- Set the correct permissions for your public/private keys (usually in
config/jwt/):sudo chmod 644 config/jwt/public.pem sudo chmod 600 config/jwt/private.pem - Ensure the files are owned by the web server user (e.g.,
www-dataon Debian/Ubuntu):sudo chown www-data:www-data config/jwt/*.pem
3. Inspect Server Logs to Confirm Header Delivery
You need to confirm if the Authorization header is actually reaching your application:
- Check Apache access logs: Add a custom log format to your Apache config to log the Authorization header. Add this to your site config:
Restart Apache, send a test request, then check the log to see if theLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Authorization}i\"" combined_with_auth CustomLog /var/log/apache2/your-project-access.log combined_with_authBearer <token>string appears. - Debug in your application: Temporarily add this code at the top of
public/index.phpto print incoming headers:
If this returnsvar_dump($_SERVER['HTTP_AUTHORIZATION']); error_log('Authorization Header: ' . $_SERVER['HTTP_AUTHORIZATION']); exit;NULL, the header is being dropped before it reaches your app.
4. Rule Out Reverse Proxy/Firewall Interception
If you’re using a reverse proxy (like Cloudflare, Nginx in front of Apache) or a WAF (Web Application Firewall), these services might filter or rewrite the Authorization header:
- Cloudflare: Check if "Bot Management" or "Security" rules are blocking the header. Temporarily disable them for testing, or add a rule to allow the Authorization header.
- Nginx (if used as proxy): Ensure your Nginx config passes the header to Apache with:
proxy_set_header Authorization $http_authorization; proxy_pass_header Authorization; - Server Firewall: Tools like
ufworiptablesrarely block headers, but if you have a WAF mod (likemod_security), check its rules for any that might flag the Authorization header.
5. Double-Check JWT Configuration
Even though it works locally, confirm your production config matches:
- Open
config/packages/lexik_jwt_authentication.yamland verify the paths to your keys are correct (absolute paths are safer on production):lexik_jwt_authentication: private_key_path: '%kernel.project_dir%/config/jwt/private.pem' public_key_path: '%kernel.project_dir%/config/jwt/public.pem' token_ttl: 3600 - Ensure you’re using the same environment variables (if any) for JWT settings in production as you do locally.
Final Test
After making changes, send a test request with curl to replicate the issue:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" https://your-server-url/api/your-resource
If this returns a successful response, you’ve fixed the header issue.
内容的提问来源于stack exchange,提问作者Alexglvr

