๋ด๊ฐ ์ฌ์ฉ์ ์์ํ๊ณ ์ํ๋ ์๋ ํ๋ ์ค์ REST API v2๊ฐ ๋ด ์ฌ์ดํธ์์ ์ฟผ๋ฆฌ ์ ๋ณด. ์๋ ํฌ์ธํธ URL์ ์ง์ ๋ฐฉ๋ฌธํ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ณต๊ฐ์ ์ผ๋ก ๋ณผ ์ ์์ต๋๋ค. ๋ํ ๋ง์ ์์ต์์์ ๋ผ์ด๋ธ ์ฌ์ดํธ๊ฐ ์๋ ํ ์คํธ ๋๋ ๋ก์ปฌ ์๋ฒ ์ฌ์ฉ์ ๋ํด ์ธ๊ธํ๊ณ ์์ต๋๋ค.
๋ด ์ง๋ฌธ์ :
- ์ด๊ฒ์ ์์ฐ ํ์ฅ์์ ์ฌ์ฉํ๊ธฐ์ํ ๊ฒ์ ๋๊น?
/wp-json/wp/v2/users/
์ฌ์ดํธ์ ๋ฑ๋ก ๋ ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ๋ณด์ฌ์ฃผ๋ ์ฌ๋๊ณผ ๊ฐ์ด ์๋ ํฌ์ธํธ๋ฅผ ๋ณผ ์์๊ฒํ๋ ๋ณด์ ์ํ์ด
์์ต๋๊น?- ์ธ์ฆ ๋ ์ฌ์ฉ์ ๋ง ์๋ ํฌ์ธํธ์ ์ก์ธ์คํ๋๋ก ํ์ฉ ํ ์ ์์ต๋๊น?
๋ณด์๊ณผ ๊ด๋ จ๋ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฅด๊ณ ์์ผ๋ฏ๋ก ๋ชจ๋ ํ์ด ๋์์ด ๋ ๊ฒ์ ๋๋ค. API ๋ฌธ์๋ ์ธ์ฆ์ ์ธ๊ธ,ํ์ง๋ง ๋ ์ง์ ์ก์ธ์ค๋๋ URL์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฅด๊ฒ ์ด์. ๋ค๋ฅธ ์ฌ๋๋ค์ ์ผ๋ฐ์ ์ผ๋ก ๋๋ฌด ๋ง์ ์ ๋ณด๋ฅผ ๋ ธ์ถ์ํค์ง ์๊ณ ์ธ๋ถ ์์ฉ ํ๋ก๊ทธ๋จ์์์ด ๋ฐ์ดํฐ์ ์ก์ธ์คํ๋๋ก ์ด๋ป๊ฒ ์ค์ ํฉ๋๊น?
๋ต๋ณ
์ด๊ฒ์ ์์ฐ ํ์ฅ์์ ์ฌ์ฉํ๊ธฐ์ํ ๊ฒ์ ๋๊น?
์. ๋ง์ ์ฌ์ดํธ์์ ์ด๋ฏธ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์ฌ์ดํธ์ ๋ฑ๋ก ๋ ๋ชจ๋ ์ฌ์ฉ์๋ฅผ ํ์ํ๋ / wp-json / wp / v2 / users /์ ๊ฐ์ ์ฌ๋์ด ์๋ ํฌ์ธํธ๋ฅผ ๋ณผ ์์๊ฒํ๋ ๋ณด์ ์ํ์ด ์์ต๋๊น?
์๋์. ์๋ฒ์ ์๋ต์ ๋ณด์๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค. ๋น ํ๋ฉด / ์ฝ๊ธฐ ์ ์ฉ ์ก์ธ์ค๋ก ๋ฌด์์ ํ ์ ์์ต๋๊น? ์๋ฌด๊ฒ๋!
๊ทธ๋ฌ๋ ์ฌ์ดํธ์์ ์ทจ์ฝํ ์ํธ๋ฅผ ํ์ฉํ๋ ๊ฒฝ์ฐ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ๊ทํ์ ์ฌ์ดํธ ์ ์ฑ ์ด๋ฏ๋ก REST API๋ ๊ทธ๊ฒ์ ๋ํด ์๋ฌด๊ฒ๋ ๋ชจ๋ฆ ๋๋ค.
์ธ์ฆ ๋ ์ฌ์ฉ์ ๋ง ์๋ ํฌ์ธํธ์ ์ก์ธ์คํ๋๋ก ํ์ฉ ํ ์ ์์ต๋๊น?
์. ๊ถํ ์ฝ๋ฐฑ ์ ์ฌ์ฉํ์ฌ์ด๋ฅผ ์ํ ํ ์ ์์ต๋๋ค .
์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
if ( 'edit' === $request['context'] && ! current_user_can( 'list_users' ) ) {
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you cannot view this resource with edit context.' ), array( 'status' => rest_authorization_required_code() ) );
}
๋ค๋ฅธ ์ฌ๋๋ค์ ์ผ๋ฐ์ ์ผ๋ก ๋๋ฌด ๋ง์ ์ ๋ณด๋ฅผ ๋ ธ์ถ์ํค์ง ์๊ณ ์ธ๋ถ ์์ฉ ํ๋ก๊ทธ๋จ์์์ด ๋ฐ์ดํฐ์ ์ก์ธ์คํ๋๋ก ์ด๋ป๊ฒ ์ค์ ํฉ๋๊น?
์ ๋ณด ๊ฐ ๋ฌด์์ธ์ง / ์ธ์ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์์ด ์ง๋ฌธ์ ๋๋ตํ๊ธฐ๊ฐ ์ด๋ ต์ต๋๋ค . ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ๋ชจ๋ ์ฐธ์กฐ ์ ์นํธ ์ํธ๋ฅผ ์ฌ์ฉ ํ๊ณ ์์ต๋๋ค.
๋ต๋ณ
์ธ์ฆ ๋ ์ฌ์ฉ์ ๋ง ์๋ ํฌ์ธํธ์ ์ก์ธ์คํ๋๋ก ํ์ฉ ํ ์ ์์ต๋๊น?
์ปจํ
์ธ ๋ฅผ ๋ณด๋ ค๋ฉด ์ธ์ฆ์ด ํ์ํ API ์๋ ํฌ์ธํธ์ ์ฌ์ฉ์ ์ ์ ๊ถํ ์ฝ๋ฐฑ์ ์ถ๊ฐ ํ ์ ์์ต๋๋ค. ๊ถํ์ด์๋ ์ฌ์ฉ์๋ ์ค๋ฅ ์๋ต์๋ฐ์ต๋๋ค"code": "rest_forbidden"
์ด๋ฅผ ์ํํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ WP_REST_Posts_Controller๋ฅผ ํ์ฅํ๋ ๊ฒ์ ๋๋ค. ๋ค์์ ๊ทธ ๊ฐ๋จํ ์์ ๋๋ค.
class My_Private_Posts_Controller extends WP_REST_Posts_Controller {
/**
* The namespace.
*
* @var string
*/
protected $namespace;
/**
* The post type for the current object.
*
* @var string
*/
protected $post_type;
/**
* Rest base for the current object.
*
* @var string
*/
protected $rest_base;
/**
* Register the routes for the objects of the controller.
* Nearly the same as WP_REST_Posts_Controller::register_routes(), but with a
* custom permission callback.
*/
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => $this->get_collection_params(),
'show_in_index' => true,
),
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'create_item' ),
'permission_callback' => array( $this, 'create_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
'show_in_index' => true,
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
),
'show_in_index' => true,
),
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
'show_in_index' => true,
),
array(
'methods' => WP_REST_Server::DELETABLE,
'callback' => array( $this, 'delete_item' ),
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
'args' => array(
'force' => array(
'default' => true,
'description' => __( 'Whether to bypass trash and force deletion.' ),
),
),
'show_in_index' => false,
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
}
/**
* Check if a given request has access to get items
*
* @param WP_REST_Request $request Full data about the request.
* @return WP_Error|bool
*/
public function get_items_permissions_check( $request ) {
return current_user_can( 'edit_posts' );
}
}
์ฝ๋ฐฑ์ด ์ก์ธ์ค ํ์ฉ ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ๋ฐ function get_items_permissions_check
์ฌ์ฉ ํ๋ ๊ถํ current_user_can
์ ์ ์ ์์ต๋๋ค. API๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ํด๋ผ์ด์ธํธ ์ธ์ฆ์ ๋ํด ์์ธํ ์์์ผ ํ ์๋ ์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ ๋ค์ ์ธ์๋ฅผ ์ถ๊ฐํ์ฌ REST API ์ง์์ผ๋ก ์ฌ์ฉ์ ์ ์ ๊ฒ์๋ฌผ ์ ํ์ ๋ฑ๋ก ํ ์ ์์ต๋๋ค. register_post_type
/**
* Register a book post type, with REST API support
*
* Based on example at: http://codex.wordpress.org/Function_Reference/register_post_type
*/
add_action( 'init', 'my_book_cpt' );
function my_book_cpt() {
$labels = array(
'name' => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
'singular_name' => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
'menu_name' => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
'name_admin_bar' => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
'add_new' => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
'add_new_item' => __( 'Add New Book', 'your-plugin-textdomain' ),
'new_item' => __( 'New Book', 'your-plugin-textdomain' ),
'edit_item' => __( 'Edit Book', 'your-plugin-textdomain' ),
'view_item' => __( 'View Book', 'your-plugin-textdomain' ),
'all_items' => __( 'All Books', 'your-plugin-textdomain' ),
'search_items' => __( 'Search Books', 'your-plugin-textdomain' ),
'parent_item_colon' => __( 'Parent Books:', 'your-plugin-textdomain' ),
'not_found' => __( 'No books found.', 'your-plugin-textdomain' ),
'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
);
$args = array(
'labels' => $labels,
'description' => __( 'Description.', 'your-plugin-textdomain' ),
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'book' ),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'show_in_rest' => true,
'rest_base' => 'books-api',
'rest_controller_class' => 'My_Private_Posts_Controller',
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
);
register_post_type( 'book', $args );
}
๋น์ ์ ๋ณผ ์ ์์ต๋๋ค rest_controller_class
์ฌ์ฉํ๋ My_Private_Posts_Controller
๋์ ๊ธฐ๋ณธ ์ปจํธ๋กค๋ฌ๋ฅผ.
์ค๋ช ์ ์ธ๋ถ์์ REST API๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ๋ํ ์ข์ ์์ ์ค๋ช ์ ์ฐพ๊ธฐ๊ฐ ์ด๋ ค์ ์ต๋๋ค . ๊ธฐ๋ณธ ์ปจํธ๋กค๋ฌ ํ์ฅ์ ๋ํ ํ๋ฅญํ ์ค๋ช ์ ์ฐพ์ ์ผ๋ฉฐ ์ฌ๊ธฐ ์ ์๋ ํฌ์ธํธ ์ถ๊ฐ์ ๋ํ ์ฒ ์ ํ ์๋ด์๊ฐ ์์ต๋๋ค.
๋ต๋ณ
๋ก๊ทธ์ธํ์ง ์์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ REST API๋ฅผ ์ ํ ์ฌ์ฉํ์ง ๋ชปํ๋๋ก ์ฐจ๋จํ๋ ๋ฐ ์ฌ์ฉํ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server){
if ( !is_user_logged_in() ) {
wp_die('sorry you are not allowed to access this data','cheatin eh?',403);
}
}
๋ต๋ณ
add_filter( 'rest_api_init', 'rest_only_for_authorized_users', 99 );
function rest_only_for_authorized_users($wp_rest_server)
{
if( !is_user_logged_in() )
wp_die('sorry you are not allowed to access this data','Require Authentication',403);
} }
function json_authenticate_handler( $user ) {
global $wp_json_basic_auth_error;
$wp_json_basic_auth_error = null;
// Don't authenticate twice
if ( ! empty( $user ) ) {
return $user;
}
if ( !isset( $_SERVER['PHP_AUTH_USER'] ) ) {
return $user;
}
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
remove_filter( 'determine_current_user', 'json_authenticate_handler', 20 );
$user = wp_authenticate( $username, $password );
add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );
if ( is_wp_error( $user ) ) {
$wp_json_basic_auth_error = $user;
return null;
}
$wp_json_basic_auth_error = true;
return $user->ID;}add_filter( 'determine_current_user', 'json_authenticate_handler', 20 );