Yesod框架POST请求调用REST API遇303重定向问题求助
Alright, let's break down why your POST request to postBanksR is redirecting to auth/google even after you've tried bypassing authorization, while GET requests work fine. Here are the most likely culprits and fixes:
1. Check for Forced Authentication Calls in Your POST Handler
The most common reason for this redirect is that your POST handler is using functions that explicitly require authentication—like requireAuth, requireAuthId, or requireAuthPair—even if you've set isAuthorized to return Authorized.
Yesod's requireAuth family of functions don't just rely on isAuthorized; they actively check if a user is logged in, and redirect to the auth route if not. For example:
postBanksR :: YourParamType -> Handler TypedContent postBanksR a = do user <- requireAuth -- This line triggers the redirect if no user is logged in -- REST API call logic here
Fix: Temporarily comment out any requireAuth-style calls in your POST handler for testing. If you need to keep them for production, you can simulate a logged-in user in Postman by capturing the session cookie after logging in via the OAuth flow, then adding that cookie to your POST requests.
2. Verify Your isAuthorized Pattern Matching
Double-check that your isAuthorized definition is correctly targeting the postBanksR route. It's easy to mix up route constructors or miss parameters, which would make your authorization rule ineffective.
For example, if your route is defined like:
/post-banks/#MyParam postBanksR POST
Your isAuthorized should match exactly:
isAuthorized (postBanksR a) _ = return Authorized -- Make sure the constructor and parameter (a) match your route definition
If the pattern doesn't match, Yesod will fall back to your default isAuthorized rule (which probably enforces OAuth authentication), causing the redirect.
3. Don't Disable yesodMiddleware Globally
Commenting out yesodMiddleware is a blunt approach that breaks essential Yesod functionality (like content type handling, error pages, and more). This isn't necessary to bypass authorization for a single route.
Fix: Restore your yesodMiddleware definition:
yesodMiddleware :: ToTypedContent res => Handler res -> Handler res yesodMiddleware = defaultYesodMiddleware
Authorization checks are handled by isAuthorized and route-specific logic, not the base middleware.
4. Check Your App's authRoute Configuration
Yesod uses the authRoute function to determine where to redirect unauthenticated users. If your app defines authRoute = Just AuthR, any request that triggers an authentication check (even accidentally) will redirect there.
While isAuthorized returning Authorized should prevent this, if there's a mismatch in your route pattern matching, the default auth rule might take over. To test this temporarily, you can override authRoute for testing:
authRoute _ = Nothing -- Disables auth redirects globally (revert after testing!)
If this fixes the redirect, you know the issue is with your isAuthorized pattern matching or handler-level authentication calls.
5. Enable Debug Logs to Trace the Redirect
Yesod's debug logs can show exactly where the redirect is being triggered. Add the following to your config/settings.yml to enable detailed logging:
development: logLevel: Debug
Run your app and send the POST request again—look for log lines mentioning "redirect" or "authorization" to pinpoint the exact step causing the 303.
内容的提问来源于stack exchange,提问作者Tanmay Bhattacharya

