Login bằng php-jwt thay cho session, cookie truyền thống

install:

composer require firebase/php-jwt:dev-master
composer require zendframework/zend-config:~2.3
composer require zendframework/zend-http:~2.3

Tham khảo: sitepoint
=============
index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title></title>
    <link rel="stylesheet" href="">
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.12.2.min.js'></script>
</head>
<body>
<form id="frmLogin" action="">
    ** username: song <br/>
    ** password: 123456 <br/>
    <input type="text" name="username" /> <br/>
    <input type="password" name="password" /> <br/>
    <input type="submit" /> <br/>
</form>
<hr/>
<button id="btnGetResource">Get Resource</button> <br/>
<div id="resourceContainer"></div>
<script>
$(document).ready(function() {
    $(function () {
        var store = store || {};
        /*
         * Sets the jwt to the store object
         */
        store.setJWT = function(data){
            this.JWT = data;
        }
        /*
         * Submit the login form via ajax
         */
        $("#frmLogin").submit(function(e){
            e.preventDefault();
            $.post('token.php', $("#frmLogin").serialize(), function(data){
                store.setJWT(data.JWT);
            }).fail(function(){
                alert('error');
            });
        });
        $("#btnGetResource").click(function(e){
            e.preventDefault();
            $.ajax({
                url: 'image.php',
                beforeSend: function(request){
                    request.setRequestHeader('Authorization', 'Bearer ' + store.JWT);
                },
                type: 'GET',
                success: function(data) {
                    $("#resourceContainer").html('<img src="data:image/jpeg;base64,' + data.img + '" />');
                },
                error: function() {
                    alert('error');
                }
            });
        });
    });
});
</script>
</body>
</html>

token.php

<?php
require_once('vendor/autoload.php');

use Zend\Config\Factory;
use Zend\Http\PhpEnvironment\Request;
use Firebase\JWT\JWT;

/*
 * Application setup, database connection, data sanitization and user
 * validation routines are here.
 */


$request = new Request();
/*
 * Validate that the request was made using HTTP POST method
 */
if ($request->isPost()) {
    /*
     * Simple sanitization
     */
    $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
    $password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
    if ($username && $password) {
        try {
            $config = Factory::fromFile(dirname(__FILE__) . '/config.php', true); // Create a Zend Config Object
            if ($username == 'song' && $password == '123456') {

                $id = 1;
                $tokenId    = base64_encode(mcrypt_create_iv(32));
                $issuedAt   = time();
                $notBefore  = $issuedAt + 10;  //Adding 10 seconds
                $expire     = $notBefore + 60; // Adding 60 seconds
                $serverName = $config->get('serverName');

                /*
                 * Create the token as an array
                 */
                $data = [
                    'iat'  => $issuedAt,         // Issued at: time when the token was generated
                    'jti'  => $tokenId,          // Json Token Id: an unique identifier for the token
                    'iss'  => $serverName,       // Issuer
                    'nbf'  => $notBefore,        // Not before
                    'exp'  => $expire,           // Expire
                    'data' => [                  // Data related to the signer user
                        'userId'   => $id, // userid from the users table
                        'userName' => $username, // User name
                    ]
                ];

                header('Content-type: application/json');

                /*
                 * Extract the key, which is coming from the config file.
                 *
                 * Best suggestion is the key to be a binary string and
                 * store it in encoded in a config file.
                 *
                 * Can be generated with base64_encode(openssl_random_pseudo_bytes(64));
                 *
                 * keep it secure! You'll need the exact key to verify the
                 * token later.
                 */
                $secretKey = $config->get('jwt')->get('key');

                /*
                 * Extract the algorithm from the config file too
                 */
                $algorithm = $config->get('jwt')->get('algorithm');

                /*
                 * Encode the array to a JWT string.
                 * Second parameter is the key to encode the token.
                 *
                 * The output string can be validated at http://jwt.io/
                 */
                $jwt = JWT::encode(
                    $data,      //Data to be encoded in the JWT
                    $secretKey, // The signing key
                    $algorithm  // Algorithm used to sign the token, see https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-3
                );

                $unencodedArray = ['JWT' => $jwt];
                echo json_encode($unencodedArray);
            } else {
                header('HTTP/1.0 401 Unauthorized');
            }
        } catch (Exception $e) {
            header('HTTP/1.0 500 Internal Server Error');
        }
    } else {
        header('HTTP/1.0 400 Bad Request');
    }
} else {
    header('HTTP/1.0 405 Method Not Allowed');
}

image.php

<?php
chdir(dirname(__DIR__));

require_once('vendor/autoload.php');

use Zend\Config\Config;
use Zend\Config\Factory;
use Zend\Http\PhpEnvironment\Request;
use Firebase\JWT\JWT;

/*
 * Get all headers from the HTTP request
 */
$request = new Request();

if ($request->isGet()) {
    $authHeader = $request->getHeader('authorization');

    /*
     * Look for the 'authorization' header
     */
    if ($authHeader) {
        /*
         * Extract the jwt from the Bearer
         */
        list($jwt) = sscanf( $authHeader->toString(), 'Authorization: Bearer %s');

        if ($jwt) {

            $jwt = trim($jwt);

            try {
                $config = Factory::fromFile(dirname(__FILE__) . '/config.php', true); // Create a Zend Config Object
                /*
                 * decode the jwt using the key from config
                 */
                $secretKey = $config->get('jwt')->get('key');
                $token = JWT::decode($jwt, $secretKey, [$config->get('jwt')->get('algorithm')]);
                $asset = base64_encode(file_get_contents('http://lorempixel.com/200/300/cats/'));

                /*
                 * return protected asset
                 */
                header('Content-type: application/json');
                echo json_encode([
                    'img'    => $asset
                ]);

            } catch (Exception $e) {
                /*
                 * the token was not able to be decoded.
                 * this is likely because the signature was not able to be verified (tampered token)
                 */
                header('HTTP/1.0 401 Unauthorized');
            }
        } else {
            /*
             * No token was able to be extracted from the authorization header
             */
            header('HTTP/1.0 400 Bad Request');
        }
    } else {
        /*
         * The request lacks the authorization token
         */
        header('HTTP/1.0 400 Bad Request');
        echo 'Token not found in request';
    }
} else {
    header('HTTP/1.0 405 Method Not Allowed');
}

config.php

<?php
return array(
    'jwt' => array(
        'key'       => 'songpham_secret_key',     // Key for signing the JWT's, I suggest generate it with base64_encode(openssl_random_pseudo_bytes(64))
        'algorithm' => 'HS512' // Algorithm used to sign the token, see https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-3
    ),
    'serverName' => 'localhost',
);
Advertisements

7 thoughts on “Login bằng php-jwt thay cho session, cookie truyền thống

  1. Having read this I believed it was extremely informative. I appreciate you taking the time and effort to put this informative article together. I once again find myself spending way too much time both reading and leaving comments. But so what, it was still worthwhile!

  2. Oh my goodness! Incredible article dude! Thank you, However I am going through troubles with your RSS. I don’t understand the reason why I cannot join it. Is there anyone else getting similar RSS problems? Anybody who knows the solution can you kindly respond? Thanks!!

  3. I used to be suggested this blog through my cousin. I’m no longer sure whether this put up is written via him as no one else recognize such exact approximately my trouble. You are amazing! Thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s