- Composer. Composer will be used for dependency management in your CodeIgniter project
- A local database instance. While MySQL will be used in this tutorial, you are free to select your preferred database service
- Postman or a similar application to test our endpoints. You can also use cURL to test your endpoints
- Name
- Amount paid to retain the company’s services (Retainer fee)
- Register a new user
- Authenticate an existing user
- Add a new client
- Edit the details of an existing client
- View all clients
- View a single client by ID
- Delete a single client by ID
add_client
add_user
- UserModel.php
- ClientModel.php
- The email of the authenticated user. This is used in subsequent requests to validate the source of the request.
- The time when the token was generated (
iat
). - The time when the token expires (exp). This is gotten by adding the.
JWT_TIME_TO_LIVE
value from our .env file to the current time. - A name.
- An email address in a valid format that is not less than 8 characters and not more than 255 characters.
- A password that is not less than 8 characters and not more than 255 characters.
- An email address in a valid format that is not less than 8 characters and not more than 255 characters. Additionally the email address must correspond to that of a saved user.
- A password is not less than 8 characters and not more than 255 characters. As with the email address, the hash of the provided password must match the stored password hash associated with the provided email address.
- Twitter: https://twitter.com/yemiwebby
- GitHub: https://github.com/yemiwebby
- Website: https://yemiwebby.com.ng/
-
Oluyemi Olususi
-
Marcus Battle
-
Diane Phan
By Oluyemi Olususi 2020-11-19
The growing use and applications of cloud services necessitates a more efficient architectural style than the Simple Object Access Protocol (SOAP). REST (REpresentational State Transfer) allows for a light-weight, stateless communication between clients and the Application Programming Interface (API). Because the communication is stateless, access control for Restful APIs is based on tokens which carry enough information to determine whether or not the client is authorized to perform the requested action on the resource.
In this tutorial, I will use CodeIgniter to build a RESTful API. CodeIgniter is a powerful PHP framework with a very small footprint which allows developers to build full-scale web applications.
Prerequisites
A basic understanding of CodeIgniter will be helpful in this tutorial. However, I will provide explanations and links to official documentation throughout the tutorial. If you’re unclear on any concept, you can review the linked material before continuing with the tutorial.
Additionally, you need to have the following installed on your system:
What We’ll Build
To demonstrate how to build a secure CodeIgniter API, we’ll build an API that will be used to manage the client database for a company. This database contains the following data on each client:
The API built at the end of this tutorial will have the following functionalities:
Features 3 to 7 will be restricted to authenticated users.
Getting Started
Create a new CodeIgniter project using Composer.
composer create-project codeigniter4/appstarter ci-secure-api
This will create a new CodeIgniter project within a folder named ci-secure-api. Once the installation is completed, move into the newly created project folder from the terminal and run the application on the local development server that comes installed with CodeIgniter. Use the following command to achieve that:
// move into the project$ cd ci-secure-api// run the application$ php spark serve
Navigate to http://localhost:8080/ from your browser to view the welcome page.
Environment Variables Preparation
Now that CodeIgniter is installed and running, the next step is to provide environment variables that will be used by our application. Stop the application from running by pressing CTRL + C
on the keyboard and proceed to make a copy of the .env file named .env using the command below:
$ cp env .env
CodeIgniter starts up in production mode by default. But for the sake of this tutorial, we will change it to development. To achieve that, uncomment the line shown below and set it to development:
CI_ENVIRONMENT = development
Next, create a database within your local environment and uncomment the following variables to update each values to set up a successful connection to the database:
database.default.hostname = localhostdatabase.default.database = YOUR_DATABASEdatabase.default.username = YOUR_DATABASE_USERNAMEdatabase.default.password = YOUR_DATABASE_PASSWORDdatabase.default.DBDriver = MySQLi # this is the driver for a MySQL connection. There are also drivers available for postgres & SQLite3.
Replace the YOUR_DATABASE
, YOUR_DATABASE_USERNAME
, and YOUR_DATABASE_PASSWORD
placeholders with your own values.
Migrations and seeders
Now that we have created a database and set up a connection to it, we will create migrations for both the user
and client
table. Migration files are generally useful for creating a proper database structure. The migrations and seeders will be created using the CodeIgniter CLI tool.
Issue the following command in terminal:
$ php spark migrate:create
The CLI will ask you to name the migration file after which it will create the migration file in the App/Database/Migrations directory. For this tutorial, you will create two migration files named:
The migration file name will be prefixed with a numeric sequence in the date format of YYYY-MM-DD-HHIISS
. Please see the CodeIgniter documentation for a more detailed explanation.
Next, update the content of the add_client
migration file as follows:
<?phpuse CodeIgniter\Database\Migration;class AddClient extends Migration{ public function up() { $this->forge->addField([ 'id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, 'auto_increment' => true, ], 'name' => [ 'type' => 'VARCHAR', 'constraint' => '100', 'null' => false ], 'email' => [ 'type' => 'VARCHAR', 'constraint' => '100', 'null' => false, 'unique' => true ], 'retainer_fee' => [ 'type' => 'INT', 'constraint' => 100, 'null' => false, 'unique' => true ], 'updated_at' => [ 'type' => 'datetime', 'null' => true, ], 'created_at datetime default current_timestamp', ]); $this->forge->addPrimaryKey('id'); $this->forge->createTable('client'); } public function down() { $this->forge->dropTable('client'); }}
Here, we specified the fields and their corresponding data types for the Client
table.
Next, open the add_user
migration file and replace its content with the following:
<?phpuse CodeIgniter\Database\Migration;class AddUser extends Migration{ public function up() { $this->forge->addField([ 'id' => [ 'type' => 'INT', 'constraint' => 5, 'unsigned' => true, 'auto_increment' => true, ], 'name' => [ 'type' => 'VARCHAR', 'constraint' => '100', 'null' => false ], 'email' => [ 'type' => 'VARCHAR', 'constraint' => '100', 'null' => false, 'unique' => true ], 'password' => [ 'type' => 'VARCHAR', 'constraint' => '255', 'null' => false, 'unique' => true ], 'updated_at' => [ 'type' => 'datetime', 'null' => true, ], 'created_at datetime default current_timestamp', ]); $this->forge->addPrimaryKey('id'); $this->forge->createTable('user'); } public function down() { $this->forge->dropTable('user'); }}
The content above will help create the user table and its fields. Now run your migrations using the command below:
$ php spark migrate
To make development easier, seed your database with some dummy client data. The fzaninotto faker bundle is a default dependency in the CodeIgniter skeleton and this can be used to add random clients to the database. Just as was done for the migration, the CodeIgniter CLI Tool will be used to create a seeder for clients. Run the following command:
$ php spark make:seeder
The CLI will ask for a name called the ClientSeeder
. A ClientSeeder.php file will be created in the App/Database/Seeds directory. Open the file and replace its contents with the following:
<?phpnamespace App\Database\Seeds;use CodeIgniter\Database\Seeder;use Faker\Factory;class ClientSeeder extends Seeder{ public function run() { for ($i = 0; $i < 10; $i++) { //to add 10 clients. Change limit as desired $this->db->table('client')->insert($this->generateClient()); } } private function generateClient(): array { $faker = Factory::create(); return [ 'name' => $faker->name(), 'email' => $faker->email, 'retainer_fee' => random_int(100000, 100000000) ]; }}
Seed the database with dummy clients using the following command:
$ php spark db:seed ClientSeeder
At this point, the database should have a similar structure to the screenshot below:
Entity Models
For the API’s interaction with the database, CodeIgniter’s Model will be used. For this to work, two models will be created - one for the User and another for the Client.
Open the App/Models directory and create the following files:
In UserModel.php, add the following:
<?phpnamespace App\Models;use CodeIgniter\Model;use Exception;class UserModel extends Model{ protected $table = 'user'; protected $allowedFields = [ 'name', 'email', 'password', ]; protected $updatedField = 'updated_at'; protected $beforeInsert = ['beforeInsert']; protected $beforeUpdate = ['beforeUpdate']; protected function beforeInsert(array $data): array { return $this->getUpdatedDataWithHashedPassword($data); } protected function beforeUpdate(array $data): array { return $this->getUpdatedDataWithHashedPassword($data); } private function getUpdatedDataWithHashedPassword(array $data): array { if (isset($data['data']['password'])) { $plaintextPassword = $data['data']['password']; $data['data']['password'] = $this->hashPassword($plaintextPassword); } return $data; } private function hashPassword(string $plaintextPassword): string { return password_hash($plaintextPassword, PASSWORD_BCRYPT); } public function findUserByEmailAddress(string $emailAddress) { $user = $this ->asArray() ->where(['email' => $emailAddress]) ->first(); if (!$user) throw new Exception('User does not exist for specified email address'); return $user; }}
The beforeInsert
and beforeUpdate
functions allow you to perform an operation on the User entity before saving it to the database. In this case, the user’s password is hashed before it is saved to the database.
Add the following code to the ClientModel.php file:
<?phpnamespace App\Models;use CodeIgniter\Model;use Exception;class ClientModel extends Model{ protected $table = 'client'; protected $allowedFields = [ 'name', 'email', 'retainer_fee' ]; protected $updatedField = 'updated_at'; public function findClientById($id) { $client = $this ->asArray() ->where(['id' => $id]) ->first(); if (!$client) throw new Exception('Could not find client for specified ID'); return $client; }}
The $table
field lets the Model know which database table it works with primarily. $allowedFields
lets the Model know which columns in the table can be updated. The findClientById
function provides a clean abstraction to retrieve a client from the database based on the id
provided.
With the Models and database implemented, users can be added and authenticated. Authorized users can also interact with current clientele.
JWT Implementation
JSON Web Tokens will be used to authenticate users and prevent unauthorized users from viewing the list of clients. For this to work, the API provides a token when the user registers or logs in successfully. This token will be appended to the header of subsequent requests to ensure that the API can identify the user making a request. In this tutorial, the firebase/php-jwt bundle will be used to generate the tokens. Run the following to install it using composer:
$ composer require firebase/php-jwt
Once the installation is complete, add the following to your .env file:
#JWT_SECRET_KEY key is the secret key used by the application to sign JWTS. Pick a stronger one for production.JWT_SECRET_KEY=kzUf4sxss4AeG5uHkNZAqT1Nyi1zVfpz #JWT_TIME_TO_LIVE indicates the validity period of a signed JWT (in milliseconds)JWT_TIME_TO_LIVE=3600
Next, create a helper function to get the secret key in the Services class. Go to App/Config/Services.php and add the following:
public static function getSecretKey(){ return getenv('JWT_SECRET_KEY');}
Create JWT Helper
To help with the generation and verification of tokens, a Helper file will be created. This allows us to separate concerns in our application. In the App/Helpers directory create a file name jwt_helper.php. Your helper file should look like this:
<?phpuse App\Models\UserModel;use Config\Services;use Firebase\JWT\JWT;function getJWTFromRequest($authenticationHeader): string{ if (is_null($authenticationHeader)) { //JWT is absent throw new Exception('Missing or invalid JWT in request'); } //JWT is sent from client in the format Bearer XXXXXXXXX return explode(' ', $authenticationHeader)[1];}function validateJWTFromRequest(string $encodedToken){ $key = Services::getSecretKey(); $decodedToken = JWT::decode($encodedToken, $key, ['HS256']); $userModel = new UserModel(); $userModel->findUserByEmailAddress($decodedToken->email);}function getSignedJWTForUser(string $email){ $issuedAtTime = time(); $tokenTimeToLive = getenv('JWT_TIME_TO_LIVE'); $tokenExpiration = $issuedAtTime + $tokenTimeToLive; $payload = [ 'email' => $email, 'iat' => $issuedAtTime, 'exp' => $tokenExpiration, ]; $jwt = JWT::encode($payload, Services::getSecretKey()); return $jwt;}
The getJWTFromRequest
function checks the Authorization header of the incoming request and returns the token value. If the header is missing, it throws an exception which in turn causes an HTTP_UNAUTHORIZED
(401) response to be returned.
The validateJWTFromRequest
function takes the token obtained by the getJWTFromRequest
function. It decodes this token to get the email that the key was generated for. It then tries to find a user with that email address in the database. If the user was not found, the User Model throws an exception which is caught and returned to the user as an HTTP_UNAUTHORIZED
(401) response.
The getSignedJWTForUser
function is used to generate a token for an authenticated user. The encoded JWT contains the following details:
Create Authentication Filter
In the App/Filters directory create a file named JWTAuthenticationFilter.php . This filter will allow the API check for the JWT before passing the request to the controller. If no JWT is provided or the provided JWT is expired, an HTTP_UNAUTHORIZED
(401) response is returned by the API with an appropriate error message. Add the following to your file:
<?phpnamespace App\Filters;use CodeIgniter\API\ResponseTrait;use CodeIgniter\Filters\FilterInterface;use CodeIgniter\HTTP\RequestInterface;use CodeIgniter\HTTP\ResponseInterface;use Config\Services;use Exception;class JWTAuthenticationFilter implements FilterInterface{ use ResponseTrait; public function before(RequestInterface $request, $arguments = null) { $authenticationHeader = $request->getServer('HTTP_AUTHORIZATION'); try { helper('jwt'); $encodedToken = getJWTFromRequest($authenticationHeader); validateJWTFromRequest($encodedToken); return $request; } catch (Exception $e) { return Services::response() ->setJSON( [ 'error' => $e->getMessage() ] ) ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED); } } public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) { }}
As you can see, the JWT Helper is first loaded, then the getJWTFromRequest
and validateJWTFromRequest functions are used to ensure that the request is from an authenticated user with a valid token.
Register your JWTAuthentication filter and specify the route you want it to protect. This is done in the App/Config/Filters.php file. Update the $aliases
and $filters
array as follows:
<?php namespace Config;use App\Filters\JWTAuthenticationFilter;use CodeIgniter\Config\BaseConfig;class Filters extends BaseConfig{ public $aliases = [ 'csrf' => CSRF::class, 'toolbar' => DebugToolbar::class, 'honeypot' => \CodeIgniter\Filters\Honeypot::class, 'auth' => JWTAuthenticationFilter::class // add this line ]; // global filters // method filters public $filters = [ 'auth' => [ 'before' => [ 'client/*', 'client' ], ] ];}
NOTE: The Debug toolbar will be preloaded by default. There are known conflicts as the DebugToolbar is still under construction. To disable it, comment out the 'toolbar'
item in the $globals
array.
By adding these, the before
function in JWTAuthenticationFilter.php will be called anytime a request is sent to an endpoint starting with the client. This means that the controller will only receive/handle the request if a valid token is present in the request header.
Even though we don’t have any controller, we can check to see that our application is working so far. Open Postman and make a GET request to http://localhost:8080/client. You should see something similar to the screenshot below:
Next, open the App/Controllers/BaseController.php file and add the following function:
public function getResponse(array $responseBody, int $code = ResponseInterface::HTTP_OK){ return $this ->response ->setStatusCode($code) ->setJSON($responseBody);}
This function will be used by your controllers to return JSON responses to the client.
NOTE: Don’t forget to import the ResponseInterface.
use CodeIgniter\HTTP\ResponseInterface;
BaseController
extends the CodeIgniter Controller
which provides helpers and other functions that make handling incoming requests easier. One of such functions is a validate
function which uses CodeIgniter’s validation service to check a request against rules (and error messages where necessary) specified in our controller functions. This function works well with form requests (form-data using Postman). However this would be unable to validate raw JSON requests sent to our API. This is because the content of the JSON request is stored in the body
field of the request while the content of the form-data request is stored in the post
field of the request.
To get around this, we’ll write a function that checks both fields in a request to get its content. Add the following to App/Controllers/BaseController.php:
public function getRequestInput(IncomingRequest $request){ $input = $request->getPost(); if (empty($input)) { //convert request body to associative array $input = json_decode($request->getBody(), true); } return $input;}
NOTE: Don’t forget to import the IncomingRequest class.
use CodeIgniter\HTTP\IncomingRequest;
Next, declare a function that runs the validation service against the $input
from our previous function. This function is almost the same as the inbuilt validate
function except that instead of running the check against the IncomingRequest
, we run it against the input we captured from the getRequestInput
function.
public function validateRequest($input, array $rules, array $messages =[]){ $this->validator = Services::Validation()->setRules($rules); // If you replace the $rules array with the name of the group if (is_string($rules)) { $validation = config('Validation'); // If the rule wasn't found in the \Config\Validation, we // should throw an exception so the developer can find it. if (!isset($validation->$rules)) { throw ValidationException::forRuleNotFound($rules); } // If no error message is defined, use the error message in the Config\Validation file if (!$messages) { $errorName = $rules . '_errors'; $messages = $validation->$errorName ?? []; } $rules = $validation->$rules; } return $this->validator->setRules($rules, $messages)->run($input);}
NOTE: Don’t forget to import the necessary classes.
use CodeIgniter\Validation\Exceptions\ValidationException;use Config\Services;
With this in place, let’s add the logic to register and authenticate users.
Authentication Controller
Next, create a file name Auth.php in the App/Controllers directory. Update the file as shown below:
<?phpnamespace App\Controllers;use App\Models\UserModel;use CodeIgniter\HTTP\Response;use CodeIgniter\HTTP\ResponseInterface;use Exception;use ReflectionException;class Auth extends BaseController{ /** * Register a new user * @return Response * @throws ReflectionException */ public function register() { $rules = [ 'name' => 'required', 'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[user.email]', 'password' => 'required|min_length[8]|max_length[255]' ]; $input = $this->getRequestInput($this->request); if (!$this->validateRequest($input, $rules)) { return $this ->getResponse( $this->validator->getErrors(), ResponseInterface::HTTP_BAD_REQUEST ); } $userModel = new UserModel(); $userModel->save($input); return $this ->getJWTForUser( $input['email'], ResponseInterface::HTTP_CREATED ); } /** * Authenticate Existing User * @return Response */ public function login() { $rules = [ 'email' => 'required|min_length[6]|max_length[50]|valid_email', 'password' => 'required|min_length[8]|max_length[255]|validateUser[email, password]' ]; $errors = [ 'password' => [ 'validateUser' => 'Invalid login credentials provided' ] ];$input = $this->getRequestInput($this->request); if (!$this->validateRequest($input, $rules, $errors)) { return $this ->getResponse( $this->validator->getErrors(), ResponseInterface::HTTP_BAD_REQUEST ); } return $this->getJWTForUser($input['email']); } private function getJWTForUser( string $emailAddress, int $responseCode = ResponseInterface::HTTP_OK ) { try { $model = new UserModel(); $user = $model->findUserByEmailAddress($emailAddress); unset($user['password']); helper('jwt'); return $this ->getResponse( [ 'message' => 'User authenticated successfully', 'user' => $user, 'access_token' => getSignedJWTForUser($emailAddress) ] ); } catch (Exception $exception) { return $this ->getResponse( [ 'error' => $exception->getMessage(), ], $responseCode ); } }}
Registration
To successfully register a new user the following fields are required:
The incoming request is checked against the specified rules. Invalid requests are discarded with an HTTP_BAD_REQUEST
code (400) and an error message. If the request is valid, the user data is saved and a token is returned along with the user’s saved details (excluding the password). The HTTP_CREATED
(201) response lets the client know that a new resource has been created.
Making a POST request to the register endpoint (http://localhost:8080/auth/register) with a valid name
, email address
and password
will result in a similar response to the one shown below:
Authentication
Successful authentication requires the following:
However, doing the same for the login endpoint (http://localhost:8080/auth/login) would cause an Internal Server Error (HTTP Code 500). The reason for this is that we make use of a validateUser
function in our validation rules which we have not created yet.
User Validation
Create a new directory called Validation in the app directory. Inside of the app/Validation folder, create a file named UserRules.php and add the following code to the file:
<?phpnamespace App\Validation;use App\Models\UserModel;use Exception;class UserRules{ public function validateUser(string $str, string $fields, array $data): bool { try { $model = new UserModel(); $user = $model->findUserByEmailAddress($data['email']); return password_verify($data['password'], $user['password']); } catch (Exception $e) { return false; } }}
Next, open the App/Config/Validation.php file and modify the $ruleSets
array to include your UserRules. $ruleSets
should look like this:
public $ruleSets = [ \CodeIgniter\Validation\Rules::class, \CodeIgniter\Validation\FormatRules::class, \CodeIgniter\Validation\FileRules::class, \CodeIgniter\Validation\CreditCardRules::class, \App\Validation\UserRules::class,];
With the custom validation rules in place, the authentication request works as expected. Test this sending a POST HTTP request to thehttp://localhost:8080/auth/login endpoint with the details of the user-created earlier:
Create Client Controller
For the client controller, we will specify the routes in the app/Config/Routes.php file. Open the file and add the following routes:
$routes->get('client', 'Client::index');$routes->post('client', 'Client::store');$routes->get('client/(:num)', 'Client::show/$1');$routes->post('client/(:num)', 'Client::update/$1');$routes->delete('client/(:num)', 'Client::destroy/$1');
By doing this, your API is able to handle requests with the same endpoint but different HTTP verbs accordingly.
Next, in the App/Controllers directory, create a file called Client.php. The contents of the file should be as follows:
<?phpnamespace App\Controllers;use App\Models\ClientModel;use CodeIgniter\HTTP\Response;use CodeIgniter\HTTP\ResponseInterface;use Exception;class Client extends BaseController{ /** * Get all Clients * @return Response */ public function index() { $model = new ClientModel(); return $this->getResponse( [ 'message' => 'Clients retrieved successfully', 'clients' => $model->findAll() ] ); } /** * Create a new Client */ public function store() { $rules = [ 'name' => 'required', 'email' => 'required|min_length[6]|max_length[50]|valid_email|is_unique[client.email]', 'retainer_fee' => 'required|max_length[255]' ]; $input = $this->getRequestInput($this->request); if (!$this->validateRequest($input, $rules)) { return $this ->getResponse( $this->validator->getErrors(), ResponseInterface::HTTP_BAD_REQUEST ); } $clientEmail = $input['email']; $model = new ClientModel(); $model->save($input); $client = $model->where('email', $clientEmail)->first(); return $this->getResponse( [ 'message' => 'Client added successfully', 'client' => $client ] ); } /** * Get a single client by ID */ public function show($id) { try { $model = new ClientModel(); $client = $model->findClientById($id); return $this->getResponse( [ 'message' => 'Client retrieved successfully', 'client' => $client ] ); } catch (Exception $e) { return $this->getResponse( [ 'message' => 'Could not find client for specified ID' ], ResponseInterface::HTTP_NOT_FOUND ); } }}
The index
, store,
and show
functions are used to handle requests to view all clients, add a new client, and show a single client respectively.
Next, create two functions update
and destroy
. The update
function will be used to handle requests to edit a client. None of the fields are required hence any expected value that isn’t provided in the request is removed before updating the client in the database. The destroy
function will handle requests to delete a particular client.
public function update($id) { try { $model = new ClientModel(); $model->findClientById($id); $input = $this->getRequestInput($this->request); $model->update($id, $input); $client = $model->findClientById($id); return $this->getResponse( [ 'message' => 'Client updated successfully', 'client' => $client ] ); } catch (Exception $exception) { return $this->getResponse( [ 'message' => $exception->getMessage() ], ResponseInterface::HTTP_NOT_FOUND ); } } public function destroy($id) { try { $model = new ClientModel(); $client = $model->findClientById($id); $model->delete($client); return $this ->getResponse( [ 'message' => 'Client deleted successfully', ] ); } catch (Exception $exception) { return $this->getResponse( [ 'message' => $exception->getMessage() ], ResponseInterface::HTTP_NOT_FOUND ); } }
With this in place, our API is set for consumption. Restart your application and test it by sending requests (via Postman, cURL, or your preferred application)
$ php spark serve
Add Access Token
Once you are done with the registration and login process, copy the value of the access_token
from the response. Next, click on the Authorization
tab and select Bearer Token
from the dropdown and paste the value of the access_token
copied earlier:
Create New Client
To create a new client, send a POST
HTTP request to http://localhost:8080/client:
Get All Clients
To fetch the list of Clients created so far, send a GET
HTTP request to http://localhost:8080/client:
Get Client by ID
Retrieve the details of a particular client by sending a GET
HTTP request to http://localhost:8080/client/1. In this case, 1
was used to specify the unique id
of the client that needs to be fetched from the database:
Update Existing Client
Delete Existing Client
Conclusion
In this article, we create a PHP-based API using CodeIgniter. This allowed the execution of basic CRUD (Create, Read, Update, Delete) operations on a resource (Client). Additionally, we added a layer of security by restricting access to the resource. We also learned how to structure our project in a manner that separates concerns and makes our application loosely coupled.
The entire codebase for this tutorial is available on GitHub. Feel free to explore further. Happy coding!
Oluyemi is a tech enthusiast with a background in Telecommunication Engineering. With a keen interest to solve day to day problems encountered by users, he ventured into programming and has since directed his problem solving skills at building softwares for both web and mobile. A full stack software engineer with a passion for sharing knowledge, Oluyemi has published a good number of technical articles and content on several blogs on the internet. Being tech savvy, his hobbies include trying out new programming languages and frameworks.
Authors
Reviewers
FAQs
How to create a REST API in codeigniter? ›
- Installation of Codeigniter framework on Cloudways.
- Database and table(s) creation.
- Setup libraries and permissions.
- Setup authentication and API key(s)
- Setup HTTP calls (GET, PUT, POST, DELETE)
- Test the HTTP calls.
- Step 1: Install CodeIgniter 4. ...
- Step 2: Change CodeIgniter Environment. ...
- Step 3: Configure Database. ...
- Step 4: Create A Model and Migration. ...
- Step 5: Install JWT Package. ...
- Step 6: Create Controllers.
- Import Database from /db/rest_jwt.db.
- Test it with postman/insomnia.
- Add this to body multipart form : username = dodi. password = dodi123.
- If your authentication success you will get generated token response.
- Step 1: Create items Table. In first table we must have one table with some dummy records. ...
- Step 2: Create rest.php config file. In this step we need to add one config file for rest api configuration. ...
- Step 3: Create libraries files. ...
- Step 4: Create API Controller.
- In Admin Center, click Apps and integrations in the sidebar, then select APIs > Zendesk APIs.
- Click the Settings tab, and make sure Token Access is enabled.
- Click the Add API token button to the right of Active API Tokens. ...
- Enter an API token description.
- Select the algorithm RS256 from the Algorithm drop-down menu.
- Enter the header and the payload. ...
- Download the private key from the /home/vol/privatekey. ...
- Enter the downloaded private key in the Private Key field of the Verify Signature section.
- Create a header JSON object.
- Convert the header JSON object to a UTF-8 encoded string and base64url encode it. ...
- Create a claims JSON object, including a query string hash.
- Convert the claims JSON object to a UTF-8 encoded string and base64url encode it.
Use random_bytes() and bin2hex() function to generate unique and strong API keys in PHP. The following code snippet helps you to create a random and secure string with PHP which is useful for API key/token. $key = bin2hex(random_bytes(32)); The above code will output 64 characters long string.
How to secure API with JWT? ›- Make sure that the JWT authentication is enabled for REST APIs by setting the value of servlet. jwt. auth. ...
- The incoming HTTP request for REST API call must contain the request header “Authorization” with scheme “Bearer” followed by JWT. The signature of the token and expiration date is verified by the system.
To authenticate a user, a client application must send a JSON Web Token (JWT) in the authorization header of the HTTP request to your backend API. API Gateway validates the token on behalf of your API, so you don't have to add any code in your API to process the authentication.
How do I add JWT token to Chrome? ›
- Install the Chrome extension.
- Open developer tools and select the JWT tab.
- Use a site which sends JWT bearer tokens in the Authorization HTTP header.
- See the token contents in the developer tools pane.
- Create the REST API Skeleton.
- Implement the Initial REST API Version.
- Using Okta and OAuth 2.0 to Secure the API.
- Setting Up Okta.
- Obtain an Access Token from Okta.
- Add Token Authorization to the API.
- Revoking the Access Token.
CodeIgniter provides an API Response trait that can be used with any controller to make common response types simple, with no need to remember which HTTP status code should be returned for which response types.
How to create API without framework? ›- Step 1: Setting Up Your Development Environment. Create a project directory and cd into it by running: mkdir nodejs-api. ...
- Step 2: Connecting Your Application to a Database. ...
- Step 3: Creating an API Model. ...
- Step 4: Implementing Routing in Your Application.
Any REST request includes four essential parts: an HTTP method, an endpoint, headers, and a body.
How to create REST API in JSON? ›- First of all, ensure you have NodeJs and NPM installed.
- Create a folder name of your own choice on the desired location. For now, I have created with the name: Fake-APIs.
- Run npm init inside the folder. ...
- Run npm install — save json-server. ...
- We need to start our server now. ...
- You should see a file named db.
Select Tools > Code > Generate REST API... from the toolbar. In the REST API window, keep Provider selected for API Type. By doing so, you will be able to generate API documentation as well as the server sample code that guides you in programming your service (logic). Check the Members resource to generate API.
How to create API with token? ›- Create an API token.
- Enable CORS.
- Find your Okta domain.
- Find your application credentials.
- Share app key credentials for IdPs.
- Set up SAML Tracer.
- Upgrade SAML apps to SHA256.
- Sign Okta certs with your own CA.
- 2.1. Keep it Simple. Secure an API/System – just how secure it needs to be. ...
- 2.2. Always Use HTTPS. ...
- 2.3. Use Password Hash. ...
- 2.4. Never expose information on URLs. ...
- 2.5. Consider OAuth. ...
- 2.6. Consider Adding Timestamp in Request. ...
- 2.7. Input Parameter Validation.
To do so, add an empty Web API Controller, where we will add some action methods so that we can check the Token-Based Authentication is working fine or not. Go to Solution Explorer > Right click on the Controllers folder > Add > Controller > Select WEB API 2 Controller – Empty > Click on the Add button. >
What are the three parts of a JSON Web token? ›
Anatomy of a JWT
Figure 1 shows that a JWT consists of three parts: a header, payload, and signature.
- The application or client requests authorization to the authorization server. ...
- When the authorization is granted, the authorization server returns an access token to the application.
- The application uses the access token to access a protected resource (like an API).
JSON web token (JWT), pronounced "jot", is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object.
How do I get a JWT token from my website? ›To request an access token, send a POST request containing the JWT to the DocuSign authentication service. The response to a successful request will include your access token value.
Can we use JWT without authentication? ›JWTs can be used as an authentication mechanism that does not require a database. The server can avoid using a database because the data store in the JWT sent to the client is safe.
How are JWT tokens generated? ›How is a JWT token generated? We set the signing algorithm to be HMAC SHA256 (JWT supports multiple algorithms), then we create a buffer from this JSON-encoded object, and we encode it using base64. The partial result is eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 .
How to create API in PHP step by step? ›- Create the PHP Project Skeleton for Your REST API.
- Configure a Database for Your PHP REST API.
- Add a Gateway Class for the Person Table.
- Implement the PHP REST API.
- Secure Your PHP REST API with OAuth 2.0.
- Add Authentication to Your PHP REST API.
- Create the Header and Payload. To begin we need to create header and payload JSON strings. ...
- Create Base64Url Header and Payload Strings. ...
- Create the Signature. ...
- Base64Url Encode the Signature. ...
- Create the JSON Web Token.
- The client sends it's credentials to the server.
- The server generates the token and sends it back to the client.
- The client issues a new request including the token.
- The server verifies the token and responds accordingly.
Use strong and secure authentication methods: The API should use strong and secure authentication methods, such as hashed and salted passwords or two-factor authentication.
How do I secure my Web API? ›
Use HTTPS/TLS for REST APIs
HTTPS and Transport Layer Security (TLS) offer a secured protocol to transfer encrypted data between web browsers and servers. Apart from other forms of information, HTTPS also helps to protect authentication credentials in transit.
Encryption — Having encryption enabled on the API and using https using TLS secures the channel as well as the information sent. Rate limiting and throttling — Limiting the number of requests coming into an API helps prevent abuse.
What is the difference between JWT and token? ›The main difference between JWTs and opaque tokens is that an unencrypted JWT can be interpreted by anybody that holds the token, whereas opaque tokens cannot. An unencrypted JWT consists of three parts: a header, a payload, and a signature.
How do I send a token as an API request? ›When you put a VerifyAccessToken policy at the front of your API proxy flow, apps must present a verifiable access token (also called a "bearer token") to consume your API. To do this, the app sends the access token in the request as an "Authorization" HTTP header.
What is the difference between JWT and API key? ›The main difference between API Key auth and JWT token auth is that the JWT Token is self-contained - the information asserted by the token is in the token. Whereas with an API Key the asserted information is stored in an external system.
Does Google use JWT for authentication? ›With some Google APIs, you can make authorized API calls using a signed JWT instead of using OAuth 2.0, which can save you a network request.
How to add token to API URL? ›- Go to https://<your server>/comGpsGate/api/v. 1/test where <your server> is your server URL. ...
- Go to the Tokens resources section and click to expand it.
- Enter the applicationID, username and password, and click on Execute. ...
- Copy/save this authorization key for later use.
...
(Optional) Enable JWT authentication for all Web API requests.
- Access the web. config file.
- Search for the newly-added JWTAuth line inside the <messageHandlers/> section.
- Change JWTAuth's enabled and defaultInclude attributes to "true".
Most PHP-based web applications lack the cache feature in them, but CodeIgniter comes with the cache library to develop web applications that run faster than the other PHP frameworks. And lastly, CodeIgniter has a very active and effective community, just like WordPress.
What is the advantage of CodeIgniter? ›It makes it easier for programmers to write secure PHP applications by providing several features. CodeIgniter framework can easily tackle threats like SQL injection, cross-site scripting attacks, and remote code execution. Moreover, its cookie encryption and decryption features enhance the product development process.
Why is CodeIgniter better? ›
Codeigniter is popular because of its MVC structure. This structure makes it easy to write clean and simple code. It also allows a developer to isolate parts of their code that they don't want users to access. The model-view-Controller architecture gives developers total control over how their applications work.
How do I create an API easily? ›- Determine Your Requirements. First, you'll need to determine your API requirements. ...
- Design Your API. Next, you'll need to consider API design. ...
- Develop Your API. Now, it's time to start developing your API product. ...
- Test Your API. ...
- Publish/Deploy Your API. ...
- Monitor Your API.
Creating your own APIs can seem daunting if you're new to the practice, but sticking to a design-first approach will keep you on the right track. A simple three-step process—design, verify, code—can increase your chances of building an API that benefits the people who use it.
What is the easiest way to implement API? ›The easiest way to start using an API is by finding an HTTP client online, like REST-Client, Postman, or Paw. These ready-to-use tools help you structure your requests to access existing APIs.
How to create a simple REST API in PHP? ›- → STEP #1. You can skip this step if you already have PHP installed on your computer. ...
- → STEP #2. Since PHP is a server-side language, you need to set up a server. ...
- → STEP #3. Now navigate to where you have installed XAMPP. ...
- → STEP #4. Now create another directory called server inside rest-api .
- Create an integration with an external API.
- Create a custom REST API.
- Create an access control list (ACL) rule.
- Create a custom import entity.
- Convert serialized to JSON.
- Copy fieldsets.
- Modify media library folder permissions.
- Create a "Hello, World!" Lambda function. This function returns a greeting to the caller as a JSON object in the following format: ...
- Create a "Hello, World!" API. Now create an API for your "Hello, World!" Lambda function by using the API Gateway console. ...
- Deploy and test the API. Deploy the API in the API Gateway console.
To get JSON from a REST API endpoint using PHP, you must send an HTTP GET request to the REST API server and provide an Accept: application/json request header. The Accept: application/json header tells the REST API server that the API client expects to receive data in JSON format.
How to generate token in REST API in PHP? ›- Create a file for creating a user.
- Connect to database and user table.
- Assign submitted data to object properties.
- Use the create() method.
- Create the user object class.
- Add a create() method.
- Output.
- Establish Database.
- Provide Data in Database.
- Connect Database with PHP.
- Build API – GET Request.
- Test API with POSTMAN.
- Create API – GET Single data.
- Develop an API – POST Request for Insert & Update.
- Build API – DELETE Request.
Can I create my own API? ›
The easiest way to develop your API product is to use a tool. For instance, you can build your API using Akana. With Akana, you have two ways to develop your API: Create an API product that exposes ('proxies') an existing resource.
How to create service request through REST API? ›- Log in to BMC Helix Innovation Studio.
- On the Workspace tab, select the application from which you want to connect to a RESTful service.
- Click the Web APIs tab and click New.
- On the Properties tab, provide a name for the RESTful Service, such as JIRA API.
For example, a REST API would use a GET request to retrieve a record, a POST request to create one, a PUT request to update a record, and a DELETE request to delete one. All HTTP methods can be used in API calls. A well-designed REST API is similar to a website running in a web browser with built-in HTTP functionality.
How to use JSON API in PHP? ›- Define an object containing a "limit" property and value.
- Convert the object into a JSON string.
- Send a request to the PHP file, with the JSON string as a parameter.
- Wait until the request returns with the result (as JSON)
- Display the result received from the PHP file.
In PHP, there are several frameworks available that make it easy to create REST APIs, including Laravel, Slim, and Lumen. These frameworks provide a range of features and libraries to help developers create APIs quickly and efficiently, including support for routing, request and response handling, and data validation.
What is the difference between Lambda and API? ›Key Differences Between AWS Lambda Function URLs & Amazon API Gateway. API Gateway supports Caching, proxy to AWS services, WebSocket, Usage Plan, Manage API key & Access logs in CloudWatch, these are features not available in Lambda function URL. API Gateway supports Custom Domain & Integration with AWS WAF.
How do I create an API in API Gateway? ›- Open the API Gateway console .
- Choose Create API.
- Under HTTP API, choose Build.
- Choose Add integration, and then choose an AWS Lambda function or enter an HTTP endpoint.
- For Name, enter a name for your API.
- Choose Review and create.
- Choose Create.
A REST API in API Gateway is a collection of resources and methods that are integrated with backend HTTP endpoints, Lambda functions, or other AWS services. You can use API Gateway features to help you with all aspects of the API lifecycle, from creation through monitoring your production APIs.