Spring Boot CSRF配置需求:仅为直接访问URL启用令牌,REST API禁用
Great question! This is a really common setup when you have an app that serves both user-facing web pages (which need CSRF protection) and machine-to-machine REST APIs (which don't). Let's cover how to implement this in a couple of the most popular frameworks—pick the one that matches your tech stack!
Spring Boot (Spring Security)
Spring Security makes this straightforward with its flexible configuration. You can explicitly exclude your API paths from CSRF validation while keeping it enabled for all other routes.
Here's a complete configuration example:
@Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // First, set up your authorization rules .authorizeHttpRequests(auth -> auth .requestMatchers("/api/**").permitAll() // Adjust this to match your API's auth requirements .anyRequest().authenticated() ) // Configure CSRF: ignore API paths, protect everything else .csrf(csrf -> csrf .ignoringRequestMatchers("/api/**") // POST/PUT/DELETE requests to /api/** will skip CSRF token checks ) // Add other security configs like form login as needed .formLogin(form -> form.permitAll()); return http.build(); } }
- Replace
/api/**with your actual API path prefix (e.g.,/v1/**or/internal-api/**) - User-facing routes (like
/dashboard,/profile) will automatically enforce CSRF validation for unsafe HTTP methods (POST/PUT/DELETE) - REST API endpoints will bypass CSRF checks entirely
Express.js (Node.js)
For Express apps, use the csurf middleware and conditionally apply it only to non-API routes. You'll also need cookie-parser to handle CSRF token storage.
First, install the dependencies:
npm install csurf cookie-parser
Then set up your app with conditional CSRF middleware:
const express = require('express'); const csurf = require('csurf'); const cookieParser = require('cookie-parser'); const app = express(); // Parse cookies first (required for csurf) app.use(cookieParser()); // Apply CSRF middleware only to non-API routes app.use((req, res, next) => { // Skip CSRF for any request starting with /api if (req.path.startsWith('/api')) { return next(); } // Enable CSRF for all other routes csurf({ cookie: true })(req, res, next); }); // Example API route: no CSRF required app.post('/api/users', (req, res) => { res.json({ success: true, message: 'User created' }); }); // Example user-facing route: CSRF required app.get('/checkout', (req, res) => { // Pass the CSRF token to your frontend template res.render('checkout', { csrfToken: req.csrfToken() }); }); app.listen(3000, () => console.log('Server running on port 3000'));
- Frontend forms on non-API routes need to include the CSRF token either as a hidden input (
<input type="hidden" name="_csrf" value="<%= csrfToken %>">) or as anX-CSRF-Tokenrequest header - API requests will work without any CSRF token attached
General Best Practices
- Use a consistent API prefix: Group all your REST endpoints under a single prefix (like
/api/) to make it easy to exclude them from CSRF checks - Use stateless auth for APIs: REST APIs typically use JWT, OAuth2, or API keys (passed in request headers) instead of session cookies. These auth methods aren't vulnerable to CSRF, so skipping CSRF checks is safe here
- Test both scenarios: Verify that:
- Submitting a form from a user-facing page without a CSRF token throws an error
- Calling your API endpoints without a CSRF token works as expected
内容的提问来源于stack exchange,提问作者Kraken

