New Jan 16, 2026

Spring Boot JWT cookies not sent cross-site from React frontend on Vercel -> Render backend (403 Forbidden)

Libraries, Frameworks, etc. All from Newest questions tagged reactjs - Stack Overflow View Spring Boot JWT cookies not sent cross-site from React frontend on Vercel -> Render backend (403 Forbidden) on stackoverflow.com

I have a Spring Boot backend hosted on Render and a React frontend hosted on Vercel. I’m trying to store JWT tokens in cookies and send them cross-site, but my POST requests to protected endpoints return 403 Forbidden.

Backend setup:

Spring Boot cookie configuration:

@Value("${app.security.cookies-secure}")
private boolean cookiesSecure;

@Value("${app.security.cookies-same-site}") private String cookieSameSite;

private ResponseCookie buildCookie(String name, String value, long maxAgeSeconds) { return ResponseCookie.from(name, value) .httpOnly(true) .secure(cookiesSecure) .path("/") .sameSite(cookieSameSite) .maxAge(maxAgeSeconds) .build(); }

Properties/env variables:

# Production
app.security.cookies-secure=${APP_SECURITY_COOKIES_SECURE:true}
app.security.cookies.same-site=${APP_SECURITY_COOKIES_SAME_SITE:None}
app.security.cors.allowed-origins=${CORS_ALLOWED_ORIGINS:http://localhost:5173}

Spring Security CORS config:

@Value("${app.security.csrf-enabled}")
private boolean csrfEnabled;

@Value("${app.security.cors.allowed-origins:http://localhost:5173}") private String allowedOrigins;

@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList(allowedOrigins.split(","))); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true);

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; }

SecurityFilterChain:

Frontend setup:

Axios client:

const apiClient = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080/api',
    withCredentials: true,
    headers: {
        'Content-Type': 'application/json'
    }
});

POST request example:

export const createMealItem = async (data: CreateMealRequest): Promise<MealResponse> => {
    const response = await apiClient.post('/meals', data);
    return response.data;
}

Locally (docker-compose up --build + npm run dev) everything works: cookies are set and sent.

On Render/Vercel however...

POST https://example.onrender.com/api/meals
Status: 403 Forbidden

Render env variables

KEY VALUE
APP_SECURITY_COOKIES_SAME_SITE None
APP_SECURITY_COOKIES_SECURE true
CORS_ALLOWED_ORIGINS https://example.vercel.app

What I’ve tried

Why are my cookies not being sent with POST requests in production, causing 403 errors, even though they are set correctly in the response?

Are there any Spring Boot or browser-specific cross-site considerations I might be missing?

Edit: Had to disable Block third-party cookies, still get 403 from my backend on POST/PUT requests.

Scroll to top