W
Wasp-lang•4mo ago
David

Deployed /auth/me blocked by CORS policy

I've just deployed my app using wasp cli to fly.io but I get this error when opening my site from Google Chrome (works fine on Safari):
Access to XMLHttpRequest at 'https://foobar-server.fly.dev/auth/me' from origin 'https://www.foobar.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to XMLHttpRequest at 'https://foobar-server.fly.dev/auth/me' from origin 'https://www.foobar.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I set environment variables and the email sender works just fine. Did I miss something? Or should I try adding global middleware? If so, could someone explain the origins here? Do I put in my fly io links/actual domain/domain with www?
import cors from 'cors'
import { config, type MiddlewareConfigFn } from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {
// Example of adding an extra domains to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, 'https://example1.com', 'https://example2.com'] }))
return middlewareConfig
}
import cors from 'cors'
import { config, type MiddlewareConfigFn } from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {
// Example of adding an extra domains to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, 'https://example1.com', 'https://example2.com'] }))
return middlewareConfig
}
28 Replies
kapa.ai
kapa.ai•4mo ago
Hi @David. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The error message you're seeing is related to Cross-Origin Resource Sharing (CORS), which is a security feature that restricts how resources on a web page can be requested from another domain. In your case, it seems like your server (https://foobar-server.fly.dev) is not allowing your client (https://www.foobar.com) to access its resources due to CORS policy. You can indeed try to solve this issue by adding global middleware to your Wasp application. The serverMiddlewareFn function you provided is a good start. In the cors function call, you should replace '<https://example1.com',> '<https://example2.com'> with the origins you want to allow. In your case, this would be '<https://www.foobar.com'.> Here is how you can modify your code:
import cors from 'cors'
import { config, type MiddlewareConfigFn } from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {
// Add your domain to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, '<https://www.foobar.com']> }))
return middlewareConfig
}
import cors from 'cors'
import { config, type MiddlewareConfigFn } from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {
// Add your domain to CORS.
middlewareConfig.set('cors', cors({ origin: [config.frontendUrl, '<https://www.foobar.com']> }))
return middlewareConfig
}
This code will allow your server to accept requests from 'https://www.foobar.com'. If you have more domains you want to allow, you can add them to the array. Remember to also set this middleware function in your main.wasp file:
app todoApp {
// ...
server: {
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import { serverMiddlewareFn } from "@src/serverSetup"
},
}
app todoApp {
// ...
server: {
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import { serverMiddlewareFn } from "@src/serverSetup"
},
}
Please note that CORS is a complex topic and this might not solve all your issues. If you continue to have problems, I recommend checking out the Wasp documentation on configuring middleware (https://wasp-lang.dev/docs/advanced/middleware-config#1-customize-global-middleware) and the CORS documentation (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for more information. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @David, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
David
DavidOP•4mo ago
Should I be adding the global middleware? Seems odd that /auth/me doesn't work out of the box
miho
miho•4mo ago
Check the docs for how to add a custom domain: https://wasp-lang.dev/docs/advanced/deployment/cli#using-a-custom-domain-for-your-app The env vars need to be updated 🙂
Deploying with the Wasp CLI | Wasp
Wasp CLI can deploy your full-stack application with only a single command.
David
DavidOP•4mo ago
Yes, I followed the docs start to finish, added my custom domain (including www. subdomain) and updated dns records. The domain works, the website opens, but I cannot login and console keeps spamming the CORS error I mentioned above.
No description
David
DavidOP•4mo ago
I guess I'll try to deleting the fly.io project and deploying again once I get home from work. Is there anything else I could try beforehand? actually I might have passed the www subdomain into the env secret, could this cause such issue? I'll confirm once I get home
miho
miho•4mo ago
Yep, the domain has to match 😊 let us know
David
DavidOP•4mo ago
I redeployed and now the issue appears only on the www. subdomain. Is there a way to include a subdomain in the WASP_WEB_CLIENT_URL env var? Or how should I approach this?
MEE6
MEE6•4mo ago
Wohooo @David, you just became a Waspeteer level 3!
haarismian
haarismian•4mo ago
@miho @kapa.ai @David I am having the same issue, works just fine as yourdomain.com, but at www.yourdomain.com the cors issue is present, which is also causing the opensaas template's login button to malfunction
kapa.ai
kapa.ai•4mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- The issue you're experiencing is related to the CORS policy. CORS (Cross-Origin Resource Sharing) is a security feature that restricts how resources on a web page can be requested from another domain. In your case, it seems like your server is not allowing your client (www.yourdomain.com) to access its resources due to CORS policy. This is why it works fine with yourdomain.com but not with www.yourdomain.com - they are considered different origins by the browser. You can solve this issue by adding a global middleware to your Wasp application that allows both yourdomain.com and www.yourdomain.com. Here is how you can do it:
import cors from 'cors'
import {{ config, type MiddlewareConfigFn }} from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {{
// Add your domain with and without 'www' to CORS.
middlewareConfig.set('cors', cors({{ origin: [config.frontendUrl, '<https://yourdomain.com',> '<https://www.yourdomain.com']> }}))
return middlewareConfig
}}
import cors from 'cors'
import {{ config, type MiddlewareConfigFn }} from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {{
// Add your domain with and without 'www' to CORS.
middlewareConfig.set('cors', cors({{ origin: [config.frontendUrl, '<https://yourdomain.com',> '<https://www.yourdomain.com']> }}))
return middlewareConfig
}}
This code will allow your server to accept requests from both 'https://yourdomain.com' and 'https://www.yourdomain.com'. If you have more domains you want to allow, you can add them to the array. Remember to also set this middleware function in your main.wasp file:
app todoApp {{
// ...
server: {{
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import {{ serverMiddlewareFn }} from "@src/serverSetup"
}},
}}
app todoApp {{
// ...
server: {{
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import {{ serverMiddlewareFn }} from "@src/serverSetup"
}},
}}
Please note that CORS is a complex topic and this might not solve all your issues. If you continue to have problems, I recommend checking out the Wasp documentation on configuring middleware (https://wasp-lang.dev/docs/advanced/middleware-config#1-customize-global-middleware) and the CORS documentation (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for more information. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @haarismian, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
David
DavidOP•4mo ago
yes, I have the exact same issue 😄 @miho should we solve this by redirecting www subdomain to the actual domain or with middleware as @kapa.ai mentioned?
kapa.ai
kapa.ai•4mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Both solutions can work, but they solve the problem in different ways: 1. Redirecting www to the non-www domain: This solution is done at the DNS or server level, outside of your Wasp application. It involves configuring your DNS provider or server to automatically redirect all traffic from www.yourdomain.com to yourdomain.com. This way, your users will only ever interact with yourdomain.com, and you won't have to worry about CORS issues between the www and non-www versions of your domain. However, this might not be what you want if you have a reason to keep the www version of your domain. 2. Adding middleware in your Wasp application: This solution involves modifying your Wasp application to allow both www.yourdomain.com and yourdomain.com. This is done by adding a global middleware that sets the CORS policy to allow both domains. Here's how you can do it:
import cors from 'cors'
import {{ config, type MiddlewareConfigFn }} from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {{
// Add your domain with and without 'www' to CORS.
middlewareConfig.set('cors', cors({{ origin: [config.frontendUrl, '<https://yourdomain.com',> '<https://www.yourdomain.com']> }}))
return middlewareConfig
}}
import cors from 'cors'
import {{ config, type MiddlewareConfigFn }} from 'wasp/server'

export const serverMiddlewareFn: MiddlewareConfigFn = (middlewareConfig) => {{
// Add your domain with and without 'www' to CORS.
middlewareConfig.set('cors', cors({{ origin: [config.frontendUrl, '<https://yourdomain.com',> '<https://www.yourdomain.com']> }}))
return middlewareConfig
}}
And in your main.wasp file:
app todoApp {{
// ...
server: {{
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import {{ serverMiddlewareFn }} from "@src/serverSetup"
}},
}}
app todoApp {{
// ...
server: {{
setupFn: import setup from "@src/serverSetup",
middlewareConfigFn: import {{ serverMiddlewareFn }} from "@src/serverSetup"
}},
}}
This solution gives you more control and keeps both versions of your domain operational, but it requires modifying your Wasp application. In conclusion, the best solution depends on your specific needs. If you don't have a specific reason to keep the www version of your domain, redirecting might be the simpler solution. If you want to keep both versions, you'll need to add the middleware. For more information, check out the Wasp documentation on configuring middleware (https://wasp-lang.dev/docs/advanced/middleware-config#1-customize-global-middleware) and the CORS documentation (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @David, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
David
DavidOP•4mo ago
@kapa.ai The only reason I can think of to keep www is for older users who are used to adding www. before urls. But redirection via DNS is also not possible afaik. How does wasp handle such redirections?
kapa.ai
kapa.ai•4mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Wasp itself doesn't handle redirections from www to non-www domains or vice versa. This is typically handled at the DNS or server level, not at the application level. However, you can configure your server or your DNS provider to automatically redirect all traffic from www.yourdomain.com to yourdomain.com. The exact steps to do this depend on your server software or DNS provider, so you might need to check their documentation or contact their support for specific instructions. If you're using a platform like Fly.io for deployment, you can set up a custom domain for your app and configure it to handle www and non-www traffic. You can find more information on how to do this in the Wasp documentation on using a custom domain for your app (https://wasp-lang.dev/docs/advanced/deployment/cli#using-a-custom-domain-for-your-app). If redirection via DNS or server is not possible, another option is to handle both www and non-www traffic in your Wasp application by setting the CORS policy to allow both domains, as I explained in the previous message. Remember that handling www and non-www traffic correctly is important for SEO and user experience, so it's worth taking the time to set this up correctly. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @David, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
David
DavidOP•4mo ago
Wouldn't it be better to redirect subdomain to the main domain for SEO as well? So google doesn't create 2 rankings or smth
Vinny (@Wasp)
Vinny (@Wasp)•4mo ago
hm. Weird that two of you are having this problem all of a sudden. Let me check some things and get back to you.
miho
miho•4mo ago
Redirects at the DNS level are possible with some providers (e.g. I've done it successfully with Cloudflare) and they are a good top level solution which makes it easier for you to not worry about it any more. The second solution with expanding the CORS settings is also valid. It enables you to support two domains at the same time if for what ever reason you really need to do it. Ideally, I'd go with the redirect approach. Here's a way to use multiple domains for CORS by using custom global middleware
app corsTest {
wasp: {
version: "^0.14.0"
},
title: "cors-test",
server: {
middlewareConfigFn: import { getGlobalMiddleware } from "@src/data",
}
}

route RootRoute { path: "/", to: MainPage }
page MainPage {
component: import { MainPage } from "@src/MainPage"
}

query getSomeData {
fn: import { getSomeData } from "@src/data",
entities: []
}
app corsTest {
wasp: {
version: "^0.14.0"
},
title: "cors-test",
server: {
middlewareConfigFn: import { getGlobalMiddleware } from "@src/data",
}
}

route RootRoute { path: "/", to: MainPage }
page MainPage {
component: import { MainPage } from "@src/MainPage"
}

query getSomeData {
fn: import { getSomeData } from "@src/data",
entities: []
}
import cors from "cors";
import { MiddlewareConfigFn } from "wasp/server";
import { GetSomeData } from "wasp/server/operations";

export const getSomeData: GetSomeData = async (_args, _context) => {
return {
someData: "Hello from the server!",
};
};

export const getGlobalMiddleware: MiddlewareConfigFn = (config) => {
const isDevelopment = process.env.NODE_ENV === "development";
const clientUrl = process.env.WASP_WEB_CLIENT_URL ?? "http://localhost:3000";

// Allow all origins in development, otherwise only allow the client URL.
const origin = isDevelopment ? "*" : [clientUrl, 'http://someotherurl.com'];

config.delete("cors");
config.set(
"cors",
cors({
origin,
})
);

return config;
};
import cors from "cors";
import { MiddlewareConfigFn } from "wasp/server";
import { GetSomeData } from "wasp/server/operations";

export const getSomeData: GetSomeData = async (_args, _context) => {
return {
someData: "Hello from the server!",
};
};

export const getGlobalMiddleware: MiddlewareConfigFn = (config) => {
const isDevelopment = process.env.NODE_ENV === "development";
const clientUrl = process.env.WASP_WEB_CLIENT_URL ?? "http://localhost:3000";

// Allow all origins in development, otherwise only allow the client URL.
const origin = isDevelopment ? "*" : [clientUrl, 'http://someotherurl.com'];

config.delete("cors");
config.set(
"cors",
cors({
origin,
})
);

return config;
};
miho
miho•4mo ago
Gist
Multiple domains for CORS - custom global middleware in Wasp 0.12+
Multiple domains for CORS - custom global middleware in Wasp 0.12+ - main.wasp
David
DavidOP•4mo ago
I'd prefer using a redirect if it's possible with my setup: fly.io & godaddy.com for the domain. Any info on this?
miho
miho•4mo ago
Stack Overflow
How to redirect www to non-www on GoDaddy when using Firebase hosting
I am unable to redirect www.mydomain.com to mydomain.com. I have tried adding an A record with subdomain www and IP address from firebase, but that doesn't work. Any suggestions?
David
DavidOP•4mo ago
Do I have to revert this part of the deployment docs for adding www subdomain? I can delete the CNAME, but do I have to change anything on server side? wasp deploy fly cmd --context client certs create www.mycoolapp.com
miho
miho•4mo ago
I don't think so, no. This cert was issued to be used with the Fly app and if the redirect works on DNS lvl, then it never touches the app anyways so it shouldn't matter 🙂
David
DavidOP•4mo ago
Huge thanks, it's working now!
miho
miho•4mo ago
Noice, I'm glad it worked out for you 🙂
haarismian
haarismian•4mo ago
@David what ended up working?
David
DavidOP•4mo ago
I forwarded .www subdomain to the main domain via godaddy.
haarismian
haarismian•4mo ago
Is that done by adding the cname to www? Did you add the middleware?
David
DavidOP•4mo ago
no, in godaddy there is a forwarding tab, next to dns settings. There you can add the subdomain and its redirection address.
Want results from more Discord servers?
Add your server