简体   繁体   中英

How can I secure PHP API to use in the android application?

BOOKS table

CREATE TABLE `BOOKS` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `NAME` char(255) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

addNewBook.php

<?php
$connection = mysqli_connect("...", "...", "...", "...");
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$bookName = $_POST["bookName"];

if (isset($bookName))
    $query = mysqli_query($connection, "INSERT INTO BOOKS (NAME) VALUES ('$bookName')");

I'm a newbie with the JWT and I'm trying to secure this simple API.

I want to reject the addition request if was coming from outside the android app.

I want to reject the operation when I try to add a new book using Postman, But if the request was coming from an android app (Original app not reverse engineering app) then must add it successfully.

This is a simple example because I want to understand JWT step by step.

Your help means a lot to me. Thank you.

Here's an example flow with JWT token:

  1. Client posts a login request with username and password
  2. Server creates a JWT token for client, with userid and roles.
  3. When client adds a new book, you validate the token and check if the token includes the role claim needed to add a book
  4. If so, add the book. If not, return 401 Unauthorized.

Two important things, you don't have to check the database to validate and check the roles, and you can trust the token is untampered if it validates.

For code to start with, I recommend this article: https://roytuts.com/how-to-generate-and-validate-jwt-using-php-without-using-third-party-api/

Following code is from to website, with the addition of getting the admin role (TRUE or FALSE) when validating.

Generate token:

function generate_jwt($headers, $payload, $secret = 'secret') {
    $headers_encoded = base64url_encode(json_encode($headers));
    
    $payload_encoded = base64url_encode(json_encode($payload));
    
    $signature = hash_hmac('SHA256', "$headers_encoded.$payload_encoded", $secret, true);
    $signature_encoded = base64url_encode($signature);
    
    $jwt = "$headers_encoded.$payload_encoded.$signature_encoded";
    
    return $jwt;
}

function base64url_encode($str) {
    return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}

$headers = array('alg'=>'HS256','typ'=>'JWT');
$payload = array('sub'=>'1234567890','name'=>'John Doe', 'admin'=>true, 'exp'=>(time() + 60));

$jwt = generate_jwt($headers, $payload);

Validate token:

function is_jwt_valid($jwt, $secret = 'secret') {
    // split the jwt
    $tokenParts = explode('.', $jwt);
    $header = base64_decode($tokenParts[0]);
    $payload = base64_decode($tokenParts[1]);
    $signature_provided = $tokenParts[2];

    // check the expiration time - note this will cause an error if there is no 'exp' claim in the jwt
    $expiration = json_decode($payload)->exp;
    $is_token_expired = ($expiration - time()) < 0;

    // get role here, simple admin example
    $admin = json_decode($payload)->admin;
    
    // build a signature based on the header and payload using the secret
    $base64_url_header = base64url_encode($header);
    $base64_url_payload = base64url_encode($payload);
    $signature = hash_hmac('SHA256', $base64_url_header . "." . $base64_url_payload, $secret, true);
    $base64_url_signature = base64url_encode($signature);

    // verify it matches the signature provided in the jwt
    $is_signature_valid = ($base64_url_signature === $signature_provided);
    
    if ($is_token_expired || !$is_signature_valid) {
        return FALSE;
    } else {
        return TRUE;
    }
}

$is_jwt_valid = is_jwt_valid('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJhZG1pbiI6dHJ1ZSwiZXhwIjoxNTgyNjE2MDA1fQ.umEYVDP_kZJGCI3tkU9dmq7CIumEU8Zvftc-klp-334');

Remember to replace 'secret' with your secret string, it can for example be a GUID.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM