I am attempting to post data from a form to the WordPress REST API via my Vue/Nuxt application using Axios and JWT.
I am able to obtain a valid token and save it as a cookie, but when I attempt to post the data to the API, I get a 401 Unauthorised error with the message "rest_cannot_create" - Sorry you are not allowed to post as this user.
The user in question is the one authorised by JWT. I have tried it with them as both an Author (create and edit their own posts) and Editor (can create, edit and delete their own posts), but both have the same result.
My code is below:
submitForm: function() {
let formData = {
type: 'kic_enquiries',
title: {
rendered: 'Enquiry from ' + this.firstname + ' ' + this.lastname + ' [' + new Date() + ']'
},
acf: {
enquiry_name: this.firstname + ' ' + this.lastname,
enquiry_email: this.emailaddress,
enquiry_phone: this.phonenumber,
enquiry_message: this.message
}
};
this.formSubmission.push(formData);
const bodyFormData = new FormData();
bodyFormData.set('username', 'username');
bodyFormData.set('password', 'password');
axios ({
method: 'post',
url: url + '/wp-json/jwt-auth/v1/token',
data: bodyFormData,
config: {
headers: { 'Content-Type': 'multipart/form-data' }
}
})
.then(res => {
this.$cookies.set("cookiename", res.data.token, "3MIN");
}).catch(function(error) {
console.error( 'Error', error );
}).finally(() => {
console.log('Posting form...');
axios ({
method: 'post',
url: url + '/wp-json/wp/v2/kic-enquiries',
data: JSON.stringify(this.formSubmission),
config: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization:': 'Bearer ' + this.$cookies.get("cookiename")
}
}
})
.then(submitResponse => {
console.log('Form submitted...' + submitResponse)
return submitResponse;
}).catch(function(error) {
console.error( 'Error', error );
});
});
Do I need to use Interceptors? I've seen a lot about them online but I can't find anything that explains how I need to use them for my situation.
UPDATE
Further investigation shows the token works when sent with the same settings and data as the app via Postman, so it seems to be a code issue.
Is the post failing because I'm sending the token wrongly?
UPDATE 2 - 15 Feb 2019
I've modified my code to use await/async and a watcher to check for the token to be generated, but I'm still getting the 401 error. Updated code is below:
<script>
import axios from 'axios'
export default {
data: function() {
return {
firstname: null,
lastname: null,
emailaddress: null,
phonenumber: null,
message: null,
formSubmission: [],
res: [],
authStatus: false,
token: null
}
},
methods: {
submitForm: async function() {
let formData = {
type: 'kic_enquiries',
title: {
rendered: 'Enquiry from ' + this.firstname + ' ' + this.lastname + ' [' + new Date() + ']'
},
acf: {
enquiry_name: this.firstname + ' ' + this.lastname,
enquiry_email: this.emailaddress,
enquiry_phone: this.phonenumber,
enquiry_message: this.message
},
status: 'draft'
};
this.formSubmission.push(formData);
console.log(JSON.stringify(this.formSubmission));
await this.getToken();
},
getToken: function() {
console.info('Getting token...');
const bodyFormData = new FormData();
bodyFormData.set('username', 'user');
bodyFormData.set('password', 'pass');
axios ({
method: 'post',
url: link,
data: bodyFormData,
config: {
withCredentials: true,
headers: { 'Content-Type': 'multipart/form-data' },
}
})
.then(res => {
this.$cookies.set("XSRF-TOKEN", res.data.token, "30MIN");
console.log('Cookie:' + this.$cookies.get("XSRF-TOKEN"));
}).catch(function(error) {
console.error( 'Error', error );
}).finally(() => {
this.authStatus = true;
this.token = this.$cookies.get("XSRF-TOKEN");
});
}
},
watch: {
authStatus: function() {
if (this.authStatus == true) {
console.info('Posting form...');
axios ({
method: 'post',
url: 'link,
data: this.formSubmission,
config: {
withCredentials: true,
headers: {
'Authorization:': 'Bearer ' + this.token
}
}
})
.then(submitResponse => {
console.log('Form submitted...' + submitResponse)
return submitResponse;
}).catch(function(error) {
console.error( 'Error', error );
});
}
else {
console.error('Token not generated')
}
}
}
}
</script>
So now, the form submission has to wait for the token to be generated and applied before it attempts to make the request to the API.
In the error documents I've noticed withCredentials
is being set to false
even though it's set to true
in the config. Why would that be?