RestFul API 对于删除和更新获取 403 Forbidden Codeigniter 4

RestFul API For Delete And Update Get 403 Forbidden Codeigniter 4

记住这是 codeigniter 4。

我在这里需要帮助。我正在学习在 codeigniter 4 中实现 RestFul API。 下面是我的详细代码。

路线:

$routes->resource('ApiManageMaintenance', ['controller' =>'App\Controllers\ApiData\ApiManageMaintenance']); // get, put, create, delete

ApiManageMaintenance.php :

<?php
 
namespace App\Controllers\ApiData;
use App\Controllers\BaseController;
use CodeIgniter\RESTful\ResourceController;


class ApiManageMaintenance extends ResourceController
{    

    function __construct()
    {       

        $model = new Dennis_setting_model();    
            

    }
    

    // equal to get    
    public function index()
    {          
        $Medoo = new \App\Models\Dennis_medoo_model();      
        $result = $Medoo->SelectAllMaintenance();   

        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => 'Pull Data Successfull',
            'data'     => $result
        ];            
        
        return json_encode($response); 
        
    }
    
        
    // equal to post
    public function create() {
        $version = $this->request->getVar('version');
        $reason = $this->request->getVar('reason');     

        if ($version == "" || $reason == "") {
            $response = [
                'status'   => 102,
                'error'    => 'Data Error',
                'messages' => 'Data Not Valid',
                'data' => null 
            ];         
            
            return json_encode($response);            
        }

        $array = array ('version' => $version,
                  'reason' => $reason
        );

        $Medoo = new \App\Models\Dennis_medoo_model();      
        $Medoo->InsertNewMaintenance($array);
        
        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => 'Create New Maintenance Successfull',
            'data'     => null
        ];            
        
        return json_encode($response);        

    }

    // equal to get
    public function show($id = null) {

        $Medoo = new \App\Models\Dennis_medoo_model();      
        $result = $Medoo->SelectAllMaintenance();   

        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => 'Pull Data Successfull',
            'data'     => $result
        ];            
        
        return json_encode($response); 
    }

    // equal to put    
    public function update($id = null) {
        $data = $this->request->getRawInput();
        $data['id'] = $id;

        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => 'Update Data Successfull',
            'data'     => null
        ];            
        
        return json_encode($response);
    }
    

    // equal to delete
    public function delete($id = null) {        
        $Medoo = new \App\Models\Dennis_medoo_model();
        $Medoo->DeleteMaintenance($id);
        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => 'Delete Data Successfull',
            'data'     => null
        ];            
        
        return json_encode($response);
        
    }

}

配置Filter.php

<?php namespace Config;

use CodeIgniter\Config\BaseConfig;

class Filters extends BaseConfig
{
    // Makes reading things below nicer,
    // and simpler to change out script that's used.
    public $aliases = [
        'csrf'     => \CodeIgniter\Filters\CSRF::class,
        'toolbar'  => \CodeIgniter\Filters\DebugToolbar::class,
        'honeypot' => \CodeIgniter\Filters\Honeypot::class,
        'auth' => \App\Filters\Auth::class,
        'authaccess' => \App\Filters\AuthAccess::class
    ];

    // Always applied before every request
    public $globals = [
        'before' => [
            //'honeypot'
            'csrf' => ['except' => [
                    'api/ApiManageMaintenance/delete'
                ]
            ]           
        ],
        'after'  => [
            'toolbar',
            //'honeypot'
        ],
    ];


    // Works on all of a particular HTTP method
    // (GET, POST, etc) as BEFORE filters only
    //     like: 'post' => ['CSRF', 'throttle'],
    public $methods = [
        
    ];

    // List filter aliases and any before/after uri patterns
    // that they should run on, like:
    //    'isLoggedIn' => ['before' => ['account/*', 'profiles/*']],
    public $filters = [];
}

注意:我用的是第三方数据库library => Medoo,所以忽略它。出于某种原因,我没有在 codeigniter 中使用内置框架数据库查询,因为 Medoo 对我来说看起来很简单。

然后是工作:

然后不工作:

Restful API 在邮递员中尝试删除和更新都给我一个错误:

403 - Forbidden: Access is denied. You do not have permission to view this directory or page using the credentials that you supplied.

我还在配置中添加了execption => filter.php

public $globals = [
            'before' => [
                //'honeypot'
                'csrf' => ['except' => [
                        'api/ApiManageMaintenance/delete'
                    ]
                ]           
            ],
    
        ];

我不太了解配置 filter.php 但似乎这行代码将使 api 删除工作正常进行。

'csrf' => ['except' => [
                'api/ApiManageMaintenance/delete'
            ]
    ]       

现在我的问题是:

  1. 是否有任何我遗漏或需要做的特定设置或配置 让 Restfu API 使 API Restful 工作 ?

非常感谢来自这个社区的任何帮助。

好的,最好的方法是 implelemnet restfull apici4

api ctl


<?php

namespace Modules\Shared\Controllers;

/**
 * Class BaseController
 *
 * BaseController provides a convenient place for loading components
 * and performing functions that are needed by all your controllers.
 * Extend this class in any new controllers:
 *     class Home extends BaseController
 *
 * For security be sure to declare any new methods as protected or private.
 *
 * @package CodeIgniter
 */


use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\RESTful\ResourceController;
use Modules\Auth\Config\Services;
use Myth\Auth\AuthTrait;
use Psr\Log\LoggerInterface;
use  Modules\Shared\Interfaces\UrlAggregationInterface;
use  Modules\Shared\Libraries\UrlAggregation;

class ApiController extends ResourceController
{
    use AuthTrait;

    protected $format = "";
    public object $userObject;
    public UrlAggregationInterface $urlAggregation;

    /**
     * An array of helpers to be loaded automatically upon
     * class instantiation. These helpers will be available
     * to all other controllers that extend BaseController.
     *
     * @var array
     */
    protected $helpers = [
        'cookie',
        'url',
        'from',
        'filesystem',
        'text',
        'shared'
    ];

    /**
     * Constructor.
     *
     * @param RequestInterface $request
     * @param ResponseInterface $response
     * @param LoggerInterface $logger
     */


    /**
     * @var string
     * Holds the session instance
     */
    protected $session;

    public function __construct()
    {

        $this->userObject = (object)[];
    }

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        // Do Not Edit This Line
        parent::initController($request, $response, $logger);


        $this->urlAggregation = new UrlAggregation($request);

        $requestWithUser = Services::requestWithUser();
        $this->userObject = $requestWithUser->getUser();

    }

}


分组控制

<?php namespace Modules\Auth\Controllers;


use Modules\Auth\Config\Services;
use Modules\Auth\Entities\GroupEntity;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Shared\Controllers\ApiController;

class  Group extends ApiController
{
    /**
     * index function
     * @method : GET
     */
    public function index()
    {


        $groupEntity = new GroupEntity();

        $this->urlAggregation->dataMap($groupEntity->getDataMap());


        $groupService = Services::groupService();
        $findAllData = $groupService->index($this->urlAggregation);

        return $this->respond([
            'data' => $findAllData['data'],
            'pager' => $findAllData['pager']
        ], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));


    }

    /**
     * show function
     * @method : GET with params ID
     */
    public function show($id = null)
    {
        $groupService = Services::groupService();
        $findOneData = $groupService->show($id);

        return $this->respond([
            'data' => $findOneData['data'],
            'pager' => $findOneData['pager']
        ], ResponseInterface::HTTP_OK, lang('Shared.api.receive'));


    }

    public function create()
    {


        $rules = [
            'name' => 'required|min_length[3]|max_length[255]|is_unique[auth_groups.name]',
            'description' => 'required|min_length[3]|max_length[255]',
        ];

        if (!$this->validate($rules)) {

            return $this->respond([
                'error' => $this->validator->getErrors(),
                
            ], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));

        }


        $groupEntity = new GroupEntity((array)$this->request->getVar());

        $groupService = Services::groupService();
        $groupService->create($groupEntity);


        return $this->respond([
            'data' => ''
        ], ResponseInterface::HTTP_CREATED, lang('Shared.api.save'));


    }

    /**
     * update function
     * @method : PUT or PATCH
     */
    public function update($id = null)
    {


        //get request from Vue Js

        //get request from Vue Js
        $json = $this->request->getJSON();
        if (!isset($id)) {
            $id = $json->id;
        }


        $rules = [
            'name' => 'if_exist|required|min_length[3]|max_length[255]',
            'description' => 'required|min_length[3]|max_length[255]',
        ];

        if (!$this->validate($rules)) {
            return $this->respond([
                'error' => $this->validator->getErrors(),
                
            ], ResponseInterface::HTTP_NOT_ACCEPTABLE, lang('Shared.api.validation'));

        }


        $groupEntity = new GroupEntity((array)$this->request->getVar());

        $groupService = Services::groupService();
        $groupService->update($id, $groupEntity);


        return $this->respond([
        ], ResponseInterface::HTTP_OK, lang('Shared.api.update'));


    }

    /**
     * edit function
     * @method : DELETE with params ID
     */
    public function delete($id = null)
    {

        $groupService = Services::groupService();
        $groupService->delete($id);


        return $this->respond([
        ], ResponseInterface::HTTP_OK, lang('Shared.api.remove'));


    }


}


实体

<?php namespace Modules\Auth\Entities;

use \CodeIgniter\Entity;
use CodeIgniter\I18n\Time;

class  GroupEntity extends Entity
{

   protected $id;
   protected $name;
   protected $description;


    //check type of data

//    protected $casts = ['
//    is_flag' => 'boolean'];

    protected $attributes = [
        'id' => null,
        'name' => null,
        'description' => null,

    ];
    protected $datamap = [
    ];

    protected $dates = [];

    protected $casts = [];

    protected $permissions = [];

    protected $roles = [];




}


服务层

<?php


namespace Modules\Auth\Services;


use Modules\Auth\Entities\GroupEntity;
use CodeIgniter\HTTP\ResponseInterface;
use Modules\Shared\Interfaces\UrlAggregationInterface;
use Modules\Shared\Libraries\MainService;
use Myth\Auth\Authorization\GroupModel;


class GroupService extends  MainService
{
    private  GroupModel $model;

    public function __construct()
    {
        $this->model = new  GroupModel();
    }

    /**
     * index function
     * @method : GET
     * @param UrlAggregationInterface $urlAggregation
     * @return array
     */
    public function index(UrlAggregationInterface $urlAggregation)
    {
        $pipeLine = $urlAggregation->decodeQueryParam()->getPipeLine();

        return $this->model->aggregatePagination($pipeLine);

    }

    /**
     * show function
     * @method : GET with params ID
     * @param $id
     * @return array
     */
    public function show($id)
    {
        if (is_null($id)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);

        $result = $this->model->where('id', $id)->paginate(1, 'default');

        if (is_null($result)) $this->httpException(lang('Shared.api.exist'), ResponseInterface::HTTP_NOT_FOUND);

        $data = [
            'data' => $result,
            'pager' => $this->model->pager->getDetails()
        ];
        return $data;

    }

    /**
     * create function
     * @method : POST
     * @param GroupEntity $entity
     * @throws \ReflectionException
     */
    public function create(GroupEntity $entity)
    {
        if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);


        if (!$this->model->save($entity)) {
            helper('shared');
            $this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST,serializeMessages($this->model->errors()));

        }



    }

    /**
     * update function
     * @method : PUT or PATCH
     * @param $id
     * @param GroupEntity $entity
     * @throws \ReflectionException
     */
    public function update($id , GroupEntity $entity)
    {
        if (is_null($entity)) $this->httpException(lang('Shared.api.validation'), ResponseInterface::HTTP_NOT_FOUND);



        if (!$this->model->update($id, $entity)) {

            helper('shared');
            $this->httpException(lang('Shared.api.reject'), ResponseInterface::HTTP_BAD_REQUEST,serializeMessages($this->model->errors()));

        }


    }

    /**
     * edit function
     * @method : DELETE with params ID
     * @param $id
     */
    public function delete($id )
    {

        $deleteById = $this->model->find($id);

        if (is_null($deleteById)) $this->httpException(lang('Shared.api.exist'), ResponseInterface::HTTP_NOT_FOUND);

        $this->model->delete($id);


    }
    public function getInsertId()
    {
        return $this->model->getInsertID();
    }
}


这是第 2 部分

<?php namespace Modules\Auth\Config;


use CodeIgniter\HTTP\UserAgent;
use Config\App;
use Config\Services as AppServices;
use Config\Services as BaseService;
use Modules\Auth\Libraries\RequestWithUser;
use Modules\Auth\Services\AuthService;
use Modules\Auth\Services\GroupsPermissionService;
use Modules\Auth\Services\PermissionService;
use Modules\Auth\Services\RoleRouteService;
use Modules\Auth\Services\GroupService;
use Modules\Auth\Services\UsersPermissionService;

class Services extends BaseService
{
    //--------------------------------------------------------------------

    /**
     * The Request class models an HTTP request.
     *
     * @param App|null $config
     * @param boolean $getShared
     *
     * @return RequestWithUser
     */
    public static function requestWithUser(App $config = null, bool $getShared = true)
    {
        if ($getShared) {
            return static::getSharedInstance('requestWithUser', $config);
        }

        $config = $config ?? config('App');;
        return new RequestWithUser(
            $config,
            AppServices::uri(),
            'php://input',
            new UserAgent()
        );
    }

    //--------------------------------------------------------------------


    public static function roleRoute($getShared = true)
    {
        if ($getShared) {
            return static::getSharedInstance('roleRoute');
        }

        return new RoleRouteService();
    }
//--------------------------------------------------------------------

    public static function authService($getShared = false)
    {
        if (!$getShared) {
            return new AuthService();
        }
        return static::getSharedInstance('authService');

    }
//--------------------------------------------------------------------

    public static function groupService($getShared = false)
    {
        if (!$getShared) {


            return new GroupService();
        }

        return static::getSharedInstance('groupService');
    }
//--------------------------------------------------------------------

    public static function permissionService($getShared = false)
    {
        if (!$getShared) {


            return new PermissionService();
        }

        return static::getSharedInstance('permissionService');
    }
//--------------------------------------------------------------------

    public static function groupsPermissionService($getShared = false)
    {
        if (!$getShared) {


            return new GroupsPermissionService();
        }

        return static::getSharedInstance('groupsPermissionService');
    }
//--------------------------------------------------------------------

    public static function userPermissionService($getShared = false)
    {
        if (!$getShared) {


            return new UsersPermissionService();
        }

        return static::getSharedInstance('usersPermissionService');
    }

//--------------------------------------------------------------------

}


型号

<?php namespace Myth\Auth\Authorization;

use CodeIgniter\Model;
use Modules\Auth\Entities\GroupEntity;
use Modules\Shared\Models\Aggregation;

class GroupModel extends Aggregation
{
    protected $table = 'auth_groups';
    protected $primaryKey = 'id';
    protected $returnType = GroupEntity::class;

    protected $allowedFields = [
        'name', 'description'
    ];

    protected $useTimestamps = false;

    protected $validationRules = [
        'name' => 'required|max_length[255]|is_unique[auth_groups.name,name,{name}]',
        'description' => 'max_length[255]',
    ];
    protected $validationMessages = [];
    protected $skipValidation = false;

    //--------------------------------------------------------------------
    // Users
    //--------------------------------------------------------------------

    /**
     * Adds a single user to a single group.
     *
     * @param int $userId
     * @param int $groupId
     *
     * @return bool
     */
    public function addUserToGroup(int $userId, int $groupId)
    {    
        cache()->delete("{$groupId}_users");
        cache()->delete("{$userId}_groups");
        cache()->delete("{$userId}_permissions");

        $data = [
            'user_id'  => (int) $userId,
            'group_id' => (int) $groupId
        ];

        return (bool) $this->db->table('auth_groups_users')->insert($data);
    }

    /**
     * Removes a single user from a single group.
     *
     * @param int $userId
     * @param int|string $groupId
     *
     * @return bool
     */
    public function removeUserFromGroup(int $userId, $groupId)
    {
        cache()->delete("{$groupId}_users");
        cache()->delete("{$userId}_groups");
        cache()->delete("{$userId}_permissions");

        return $this->db->table('auth_groups_users')
            ->where([
                'user_id'  => $userId,
                'group_id' => (int) $groupId
            ])->delete();
    }

    /**
     * Removes a single user from all groups.
     *
     * @param int $userId
     *
     * @return bool
     */
    public function removeUserFromAllGroups(int $userId)
    {
        cache()->delete("{$userId}_groups");
        cache()->delete("{$userId}_permissions");

        return $this->db->table('auth_groups_users')
            ->where('user_id', (int)$userId)
            ->delete();
    }

    /**
     * Returns an array of all groups that a user is a member of.
     *
     * @param int $userId
     *
     * @return array
     */
    public function getGroupsForUser(int $userId)
    {
        if (null === $found = cache("{$userId}_groups"))
        {
            $found = $this->builder()
                ->select('auth_groups_users.*, auth_groups.name, auth_groups.description')
                ->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
                ->where('user_id', $userId)
                ->get()->getResultArray();

            cache()->save("{$userId}_groups", $found, 300);
        }

        return $found;
    }

    /**
     * Returns an array of all users that are members of a group.
     *
     * @param int $groupId
     *
     * @return array
     */
    public function getUsersForGroup(int $groupId)
    {
        if (null === $found = cache("{$groupId}_users"))
        {
            $found = $this->builder()
                ->select('auth_groups_users.*, users.*')
                ->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
                ->join('users', 'auth_groups_users.user_id = users.id', 'left')
                ->where('auth_groups.id', $groupId)
                ->get()->getResultArray();

            cache()->save("{$groupId}_users", $found, 300);
        }

        return $found;
    }

    //--------------------------------------------------------------------
    // Permissions
    //--------------------------------------------------------------------

    /**
     * Gets all permissions for a group in a way that can be
     * easily used to check against:
     *
     * [
     *  id => name,
     *  id => name
     * ]
     *
     * @param int $groupId
     *
     * @return array
     */
    public function getPermissionsForGroup(int $groupId): array
    {
        $permissionModel = model(PermissionModel::class);
        $fromGroup = $permissionModel
            ->select('auth_permissions.*')
            ->join('auth_groups_permissions', 'auth_groups_permissions.permission_id = auth_permissions.id', 'inner')
            ->where('group_id', $groupId)
            ->findAll();

        $found = [];
        foreach ($fromGroup as $permission)
        {
            $found[$permission['id']] = $permission;
        }

        return $found;
    }

    /**
     * Add a single permission to a single group, by IDs.
     *
     * @param int $permissionId
     * @param int $groupId
     *
     * @return mixed
     */
    public function addPermissionToGroup(int $permissionId, int $groupId)
    {
        $data = [
            'permission_id' => (int)$permissionId,
            'group_id'      => (int)$groupId
        ];

        return $this->db->table('auth_groups_permissions')->insert($data);
    }

    //--------------------------------------------------------------------


    /**
     * Removes a single permission from a single group.
     *
     * @param int $permissionId
     * @param int $groupId
     *
     * @return mixed
     */
    public function removePermissionFromGroup(int $permissionId, int $groupId)
    {
        return $this->db->table('auth_groups_permissions')
            ->where([
                'permission_id' => $permissionId,
                'group_id'      => $groupId
            ])->delete();
    }

    //--------------------------------------------------------------------

    /**
     * Removes a single permission from all groups.
     *
     * @param int $permissionId
     *
     * @return mixed
     */
    public function removePermissionFromAllGroups(int $permissionId)
    {
        return $this->db->table('auth_groups_permissions')
            ->where('permission_id', $permissionId)
            ->delete();
    }
}


<?php

/*
 * Core Auth  routes file.
 */

$routes->group('api', ['namespace' => 'Modules\Auth\Controllers'], function ($routes) {

    $routes->resource('group', ['filter' => 'authJwt']);
    $routes->resource('permission', ['filter' => 'authJwt']);
    $routes->resource('groupPermission', ['filter' => 'authJwt']);
    $routes->resource('userPermission', ['filter' => 'authJwt']);

    $routes->group('auth', function ($routes) {

        $routes->post('signin-jwt', 'Auth::signInJwt', ['filter' => 'isSignIn']);
        $routes->post('signin', 'Auth::signIn', ['filter' => 'isSignIn']);
        $routes->get('signout', 'Auth::signOut', ['filter' => 'authJwt']);
        $routes->get('is-signin', 'Auth::isSignIn',['filter' => 'authJwt']);


        $routes->post('signup', 'Auth::signUp', ['filter' => 'isSignIn']);
        $routes->post('forgot', 'Auth::forgot', ['filter' => 'isSignIn']);

        $routes->post('reset-password-email', 'Auth::resetPasswordViaEmail', ['filter' => 'isSignIn']);
        $routes->post('reset-password-sms', 'Auth::resetPasswordViaSms', ['filter' => 'isSignIn']);

        $routes->post('activate-account-email', 'Auth::activateAccountViaEmail', ['filter' => 'isSignIn']);
        $routes->post('send-activate-email', 'Auth::sendActivateCodeViaEmail', ['filter' => 'isSignIn']);

        $routes->post('activate-account-sms', 'Auth::activateAccountViaSms', ['filter' => 'isSignIn']);
        $routes->post('send-activate-sms', 'Auth::sendActivateCodeViaSms', ['filter' => 'isSignIn']);

    });

});





答案:

在 Codeigniter 4文件夹过滤器中创建文件过滤器

输入此代码:

<?php

namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
use Codeigniter\API\ResponseTrait;
use Config\Services;
use Exception;


class FilterBasicAuth implements FilterInterface
{

    use ResponseTrait;
    public function before(RequestInterface $request, $arguments = null)
    {               
        
        header('Access-Control-Allow-Origin: *');
        header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
        
        $method = $_SERVER['REQUEST_METHOD'];
        if ($method == "OPTIONS") {
            die();
        }    
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        // Do something here
    }
}

主要代码为:

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");

        $method = $_SERVER['REQUEST_METHOD'];
        if ($method == "OPTIONS") {
            die();
        }    

然后在配置中Filters.php

输入并添加此代码的别名:

public $aliases = [             
        'cors'     => \App\Filters\FilterBasicAuth::class,
    ];

注:

I use filter name FilterBasicAuth. You can change to yours and make sure in the aliases change the name too.

就是这些。