Add CSRF token handling to contact form for enhanced security
- Introduce a hidden CSRF token input field in the contact form. - Implement a function to fetch and set the CSRF token on form load. - Update form submission logic to use FormData and re-fetch the CSRF token after successful submission.
This commit is contained in:
@@ -36,6 +36,9 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
|
|||||||
<!-- Netlify form name -->
|
<!-- Netlify form name -->
|
||||||
<input type="hidden" name="form-name" value="contact" />
|
<input type="hidden" name="form-name" value="contact" />
|
||||||
|
|
||||||
|
<!-- CSRF token field (will be filled by JS) -->
|
||||||
|
<input type="hidden" name="csrf_token" id="csrf_token" value="" />
|
||||||
|
|
||||||
<!-- Honeypot field to prevent spam -->
|
<!-- Honeypot field to prevent spam -->
|
||||||
<p class="hidden">
|
<p class="hidden">
|
||||||
<label>Don't fill this out if you're human: <input name="bot-field" /></label>
|
<label>Don't fill this out if you're human: <input name="bot-field" /></label>
|
||||||
@@ -130,19 +133,34 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const form = document.getElementById('contact-form') as HTMLFormElement;
|
async function setCsrfToken() {
|
||||||
|
try {
|
||||||
|
const res = await fetch('/api/contact?csrf=true');
|
||||||
|
if (res.ok) {
|
||||||
|
const data = await res.json();
|
||||||
|
const csrfInput = document.getElementById('csrf_token');
|
||||||
|
if (csrfInput && data.csrfToken) {
|
||||||
|
csrfInput.value = data.csrfToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Failed to fetch CSRF token', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', setCsrfToken);
|
||||||
|
|
||||||
|
const form = document.getElementById('contact-form');
|
||||||
|
|
||||||
if (form) {
|
if (form) {
|
||||||
form.addEventListener('submit', async (event) => {
|
form.addEventListener('submit', async (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
const data = Object.fromEntries(formData.entries());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/.netlify/functions/contact', {
|
const response = await fetch('/api/contact', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(data),
|
body: formData,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
@@ -157,6 +175,8 @@ const { inputs, textarea, disclaimer, button = 'Contact us', description = '' }
|
|||||||
errorElement.classList.add('hidden');
|
errorElement.classList.add('hidden');
|
||||||
}
|
}
|
||||||
form.reset(); // Clear the form
|
form.reset(); // Clear the form
|
||||||
|
// Re-fetch CSRF token after successful submission
|
||||||
|
setCsrfToken();
|
||||||
} else {
|
} else {
|
||||||
console.error('Error:', response.status);
|
console.error('Error:', response.status);
|
||||||
const errorElement = document.getElementById('form-error');
|
const errorElement = document.getElementById('form-error');
|
||||||
|
Reference in New Issue
Block a user