admin管理员组文章数量:1295726
I am not sure if this is the right way to do it but I have a react site using WordPress API as the backend. I want to store my contact form entries in WordPress so I created a custom post type
register_post_type('contact', array(
'supports' => array('title'),
'has_archive' => false,
'show_in_rest' => true,
'public' => true,
'labels' => array(
'name' => 'Contact DB',
'add_new_item' => 'Add New Contact',
'edit_item' => 'Edit Contact',
'all_items' => 'All Contacts',
),
'menu_icon' => 'dashicons-format-chat'
));
I am trying to keep it simple for now on the frontend and at least try store the title
const onSubmit = async (data) => {
try {
const response = await axios.post(
`${process.env.NEXT_PUBLIC_API_ENDPOINT}/contact`,
{
title: data.name,
}
);
} catch (err) {
console.log(err);
}
};
This should not be protected or require authorisation as It is just meant to collect contact form entries and a user doesn't need to be logged in to create records. However, I am getting a 401 error
{
"code": "rest_cannot_create",
"message": "Sorry, you are not allowed to create posts as this user.",
"data": {
"status": 401
}
}
I am not sure if this is the right way to do it but I have a react site using WordPress API as the backend. I want to store my contact form entries in WordPress so I created a custom post type
register_post_type('contact', array(
'supports' => array('title'),
'has_archive' => false,
'show_in_rest' => true,
'public' => true,
'labels' => array(
'name' => 'Contact DB',
'add_new_item' => 'Add New Contact',
'edit_item' => 'Edit Contact',
'all_items' => 'All Contacts',
),
'menu_icon' => 'dashicons-format-chat'
));
I am trying to keep it simple for now on the frontend and at least try store the title
const onSubmit = async (data) => {
try {
const response = await axios.post(
`${process.env.NEXT_PUBLIC_API_ENDPOINT}/contact`,
{
title: data.name,
}
);
} catch (err) {
console.log(err);
}
};
This should not be protected or require authorisation as It is just meant to collect contact form entries and a user doesn't need to be logged in to create records. However, I am getting a 401 error
{
"code": "rest_cannot_create",
"message": "Sorry, you are not allowed to create posts as this user.",
"data": {
"status": 401
}
}
Share
Improve this question
asked Mar 26, 2021 at 18:42
user8463989user8463989
5931 gold badge8 silver badges24 bronze badges
10
|
Show 5 more comments
1 Answer
Reset to default 3I am not sure if this is the right way to do it
I want to store my contact form entries in WordPress so I created a custom post type
It's not the only right way, but IMO, it is a good approach. :)
It is just meant to collect contact form entries and a user doesn't need to be logged in to create records. However, I am getting a 401 error
As I said in the comments, creating a post via the default endpoint (e.g. at /wp/v2/contact
in your case) requires authentication by default, i.e. in the API request, you need to associate a user having the permission to create posts on the site, e.g. yourself.
And if you visit the above link, the default authentication method is cookie-based which requires the current user be logged-in to your WordPress site, hence that method isn't suitable in your case since the contact form is available to everyone (registered/logged-in users and those who aren't).
So you might want to consider using application passwords instead, which in the past you'd need to use a plugin like this, but with WordPress 5.6+, you no longer need to use a 3rd-party plugin. :)
But I'm not going to talk further about what authentication method should you use or how should they be used, however, I still wanted to say that if I were to authenticate my API requests via JS and the current user is not logged-in to WordPress, I think I would not use JWT because it normally requires us to send our WordPress password when requesting for a token and we certainly don't want to expose our precious password! :)
This should not be protected or require authorisation
In that case, you can disable the authentication for your CPT's default API endpoint, and here's one easy way of doing it: Use a custom rest_controller_class
for your CPT.
The steps:
Extend the
WP_REST_Posts_Controller
class and modify thecreate_item_permissions_check()
method (which checks if a given request has access to create a post) like so:// File name: class-my-wp-rest-contact-controller.php class My_WP_REST_Contact_Controller extends WP_REST_Posts_Controller { public function create_item_permissions_check( $request ) { if ( ! empty( $request['id'] ) ) { return new WP_Error( 'rest_post_exists', __( 'Cannot create existing post.' ), array( 'status' => 400 ) ); } return true; } }
Then set the
rest_controller_class
to the name of the above class:// On 'init', load the above class file: require_once '/path/to/class-my-wp-rest-contact-controller.php'; // Then register your CPT: register_post_type( 'contact', array( // ... your other args. 'show_in_rest' => true, 'rest_controller_class' => 'My_WP_REST_Contact_Controller', // ... your other args. ) );
That's all, but feel free to futher customize the class (and just let me know if you need any clarification).
Update
Note that the above steps would only allow unauthenticated requests to create draft posts with basic post data like title. So basically, those steps would only help in getting rid of the rest_cannot_create
error (note the "create" vs "publish" below).
To create published posts (post_status
= publish
), the request would need to be authenticated, and if not, then you'd get an error with the code rest_cannot_publish
.
But instead of having to authenticate, you can extend the handle_status_param()
method in the REST controller class like so:
public function handle_status_param( $post_status, $post_type ) {
if ( in_array( $post_status, array( 'draft', 'publish' ) ) ) {
return $post_status;
}
return parent::handle_status_param( $post_status, $post_type );
}
So in the above example, I'm allowing unauthenticated requests to set the post status to draft
or publish
, and for other statuses, I'm letting the parent class handle it.
And note that there are other permission checks done in the (parent) REST controller class, so you'd need to check the source for the relevant code should you get another error originating from that class, and then extend the method containing that code. (Remove, bypass or modify a restriction)
Additional Notes
- If you intend on making the "contact" posts be published, then you should exclude the post type from search results by setting the
exclude_from_search
argument totrue
(or maybe just setpublic
tofalse
, then set bothpublicly_queryable
andshow_ui
totrue
).
本文标签: rest apiReact post to WordPress custom post type
版权声明:本文标题:rest api - React post to WordPress custom post type 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741625053a2389034.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
/wp/v2/contact
) requires authentication by default, i.e. in the API request, you need to include a user having the permission to create posts on the site, e.g. yourself. – Sally CJ Commented Mar 26, 2021 at 22:25