Create RESTful API with Code Igniter #4 : JWT(JSON Web Token) Concept, Login function and Decode password

in #utopian-io6 years ago

Repository

https://github.com/bcit-ci/CodeIgniter

What Will I Learn?

  • Learning the JWT (JSON Web Token) concept
  • Create login function
  • Decode password

Requirements

  • Basic PHP
  • Install Ci > 3.1
  • Local server (Xampp, Wampp, or etc)
  • Mysqli

Resources

Difficulty

Basic

Tutorial Content

This tutorial we will learn something different from the previous tutorial, in this application we use the API so our login system will use tokens, unlike ordinary login applications that only use Session, so we need to use additional tools, to make the system login using tokens. We will add the system token on user authentication on our application. We will use JSON Web tokens.

JSON Web tokens

  • What is JSON web tokens?

to help you explain what JSON web tokens are, you can see on their official website https://jwt.io . So the point is after I use this tool, Json web token is a password or token that is given to validate that if the user is valid. So the token is saved by the user and when there is an action that requires access to tokens. the user will give the token so that the system can recognize that the one to be given access is a valid user. the following is the description:

Screenshot_13.png

The structure have three things as we see in the picture above as follows:

1. Header

{
  "alg": "HS256",
  "typ": "JWT"
}

in the header it will only consist of the algorithm used "alg": "HS256" and the type is jwt "typ": "JWT".

2. Payload

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Payload is the data that we will pass to the user, we can put the data requested by the user.

3. Verify Signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

) ;

Verify Signature is the result of the hash of the header base64UrlEncode(header) and payload base64UrlEncode(payload). then combined by secret keywords your-256-bit-secret, this keyword is confidential only the server knows.

Well when we login we will get an example of a token like this

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The explanation above is a concept from JWT. to connect when all data and hashing it. We need additional tools namely https://github.com/firebase/php-jwt

Use Firebase Jwt

  • Extends the code

to use this library we can see the code and copy the file in the src folder https://github.com/firebase/php-jwt/tree/master/src.

Screenshot_14.png

After you copy you can put it in our application in the application/libararies folder.

Screenshot_15.png

  • Include the code in our app

We have extracted the code in the library, then we will use it in our code. here is the way to include the code:

UsersController.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

require_once APPPATH .'/libraries/JWT.php'; // Include the JWT.php
use  \Firebase\JWT\JWT; //namespace in jwt

class UsersController extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('user');
    }

    public function response($data) {
        $this->output
             ->set_content_type('application/json')
             ->set_status_header(200)
             ->set_output(json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES))
             ->_display();
        exit;
    }

    public function register() {
        return $this->response($this->user->save());
    }

    public function all_users() {
        return $this->response($this->user->get_all());
    }

    public function detail_user($id) {
        return $this->response($this->user->get_all($id));
    }
}
  • We will use the JWT.php file so we can include the file in our code like this require_once APPPATH .'libraries/JWT.php';

  • JWT.php file has a namespace namespace Firebase\JWT;. So we can use it as follows use \Firebase\JWT\JWT; JWT is the name of class in JWT.php.

Use tokens in the login system

We have understood the token authentification. now we will implement it in our authentication system, in the previous tutorial we have made the routing for the login.

$route['api/login']                 = "UsersController/login";

If we look at the routing above, routing $route['api/login'] uses the login function UsersController/login found in UsersController. then we will create a login function on UsersController.php.

  • Checking valid login

The first step that will be done is to check whether the user who is currently logged in is a valid user, we can make the function as follows:

public function login() {
        if (!$this->user->is_valid()) {
            return $this->response([
                'success'   => false,
                'message'   => 'Password or Email is wrong'
            ]);
        }
    }
  • We make the function login () to match what we use in the login routing and then we will create a function that is in the model that is useful for checking whether the user is valid. The function name is $this->user->is_valid().

  • So later the $this->user->is_valid() will return the boolean value, then we can check the boolean value, If the result is false. that's means , the email and password is wrong and we can send a response like this:

    return $this->response([
                'success'   => false,
                'message'   => 'Password or Email is wrong'
            ]);


  • Make function is_valid() in model.php

Now we will create thefunction is_valid () in the User.php model, This function will determine whether the user is a valid user, so what we will do is matching the email and password input by user. The following is the code that we will use.

User.php

    public function get_all($key = null, $value = null) {
        if($id != null) {
            $query  = $this->db->get_where('users', array($key => $value));
            return $query->result();
        }
        $query  = $this->db->get('users');
        return $query->result();
    }

    public function is_valid() {
        $email      = $this->input->post('email');
        $password   = $this->input->post('password');

        $hash       = $this->get_all('email', $email)[0]->password;

        if(password_verify($password, $hash))
            return true;
        return false;
    }
  • Because we use the post method on the route API we can take user input values like this:
$email      = $this->input->post('email');
$password   = $this->input->post('password');

Screenshot_18.png

$this->input->post('email'): 'email' is the key that is posted on the body.

$this->input->post('password'): 'password' is the key that is posted on the body.

  • After we get the input value, we can check whether the email entered by the user is a valid email. Therefore we can use the function that we have made in the previous tutorial, the function get_all (). We can use it by passing the $email parameters we get from $this->input->post('email');. We just want to retrieve password data we can do it as follows $this->get_all('email', $email)[0]->password

  • Now we have got the value of the password that we can save in the $hash variable, but the password that we can still in the results of hashing that we do when registered.

Screenshot_17.png

  • We have got a password that has been hashed, now we will do password_verify() to check whether the hashed password is a valid password from the user. password_verify($password, $hash) has two mandatory parameters, namely the original password $password and the password that has been hashed $hash. The result of this function is true or false.

  • Then we will check whether the result of the password_verify function is correct, If it's correct then return true if the wrong return false.

We will check whether the code that we write goes well, I will do die('User is valid'); to give the response if the email and password are correct.

public function login() {
        if (!$this->user->is_valid()) {
            return $this->response([
                'success'   => false,
                'message'   => 'Password or Email is wrong'
            ]);
        }
        die('User is valid');
    }

ezgif.com-video-to-gif (4).gif
We can see in the picture above us when the password is wrong we will get a response:

{
    "success": false,
    "message": "Password or Email is wrong"
}

We have succeeded in creating a login system in our authentication system, we also understand the basic concepts of the Json web token, in the next tutorial we will start using tokens as validations for every request we make, you can explore the use of tokens in the deeper RESTful API again, hopefully this tutorial will help you, thank you.

Curriculum

Create RESTful API with Code Igniter #1 : Basic installation, Setup configuration and Database, Create Routes API

Create RESTful API with Code Igniter #2 : Create API register, Models and Controllers, JSON Response

Create RESTful API with Code Igniter #3 : Create Endpoint for Users and User detail, Dynamic functions

Proof of workdone

https://github.com/milleaduski/RESTful-CI

Sort:  

Thank you for your contribution @duski.harahap.
We've been reviewing your tutorial and suggest the following points below:

  • Again, we suggest you put comments in your code. It helps a lot to interpret the code.

  • We suggest that you name the parameters and the variables most perceptible. What is iat?

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}



Your tutorial is very well explained, again thanks for your work on doing these tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @portugalcoin!

So far this week you've reviewed 7 contributions. Keep up the good work!

Hi @duski.harahap!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Congratulations @duski.harahap! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You received more than 1000 as payout for your posts. Your next target is to reach a total payout of 2000

Click here to view your Board of Honor
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard Ranking update - Resteem and Resteemed added

Support SteemitBoard's project! Vote for its witness and get one more award!

Hey, @duski.harahap!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!