59

I'm making an authorization system in PHP, and I came across this Bearer scheme of passing JWT tokens, I read [RFC 6750][1]. I've got the following doubts:

  1. How is this improving the security?
  2. The server responses the client with a JWT token in its body after a successful authorization and login, and now when the client makes another request, I am not clear how to actually do that, I want to send token from client in Authorization header in the request, so now should I just prefix "Bearer" to the token which I received in the previous response from the server and If yes, then server on receiving the Authorization header, should just split the string with space, and take the second value from the obtained array and then decode it? For example Authorization: Bearer fdbghfbfgbjhg_something, how is server supposed to handle this, decodeFunc(explode(" ", $this->getRequest()->getHeader("Authorization"))[1])? [1]: https://www.rfc-editor.org/rfc/rfc6750
Community
  • 1
  • 1
Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51

2 Answers2

181

1.Improving the security because if token is not sent in the header that sent in url, it will be logged by the network system, the server log ....

2.A good function to get Bearer tokens

/** 
 * Get header Authorization
 * */
function getAuthorizationHeader(){
    $headers = null;
    if (isset($_SERVER['Authorization'])) {
        $headers = trim($_SERVER["Authorization"]);
    }
    else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
        $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
    } elseif (function_exists('apache_request_headers')) {
        $requestHeaders = apache_request_headers();
        // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
        $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
        //print_r($requestHeaders);
        if (isset($requestHeaders['Authorization'])) {
            $headers = trim($requestHeaders['Authorization']);
        }
    }
    return $headers;
}

/**
 * get access token from header
 * */
function getBearerToken() {
    $headers = getAuthorizationHeader();
    // HEADER: Get the access token from the header
    if (!empty($headers)) {
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) {
            return $matches[1];
        }
    }
    return null;
}
STA
  • 30,729
  • 8
  • 45
  • 59
Ngô Văn Thao
  • 3,671
  • 1
  • 20
  • 24
  • It's a nice function, you have suggested, but the `$headers` I am returning, It will have, say: `Bearer ` so now, is it right to just explode the string by space and take the actual token, or the full string `(Bearer )` is supposed to be taken as a whole? – Ashish Ranjan Nov 14 '16 at 06:46
  • `` that's right. You can explode by space. – Ngô Văn Thao Nov 14 '16 at 07:29
  • I missed a function. XD – Ngô Văn Thao Nov 15 '16 at 05:44
  • can you please add setBearerToken function?? – Fayyaz Ali May 19 '17 at 17:39
  • 4
    I'd just use a substr() to get the actual token but not the bearer. Should be much faster than preg_match(). – InputOutput Feb 27 '18 at 15:19
  • You don't need a setBearerToken() function. Just use this line: header('Authorization: Bearer TOKEN'); // Replace TOKEN with the appropriate JWT string – OMA Aug 09 '19 at 13:21
  • And how to send bearer auth info with php curl? – user4271704 Oct 27 '19 at 14:44
  • Can you help for this? https://stackoverflow.com/questions/58581568/why-authorization-bearer-is-not-sent – user4271704 Oct 27 '19 at 17:37
  • @user4271704 look at `getAuthorizationHeader` function Auth token can be store in `Authorization`, `HTTP_AUTHORIZATION` or 'apache_request_headers' function that base on your server version. – Ngô Văn Thao Oct 28 '19 at 04:30
  • Could you please test my code in the link in comment above and let me know if it is sending Auhorization bearer? Otherwise I have to ask my host to fix it. – user4271704 Oct 28 '19 at 05:08
  • It's easier to process the token using a PSR 7 http library ```use Illuminate\Http\Request; $request = Request::capture(); if ($request->headers->get('authorization') == 'Bearer '. $token) { // authorized } else { // unauthorized }``` – 8ctopus May 30 '20 at 05:07
4

I would recommend to use the following RegEx to check, if it's a valid jwt-token:

/Bearer\s((.*)\.(.*)\.(.*))/

and access it also with matches[1].

This is the structure of a JWT-Token, see: https://jwt.io/

Unkn0wn0x
  • 1,031
  • 1
  • 12
  • 14
  • 1
    Regex is not always the recommend approach for parsing string unless you can't acheive with the existing PHP String functions. – sk8terboi87 ツ Apr 30 '17 at 04:56
  • 5
    Regex is used to find patterns. Imo, you can use regex to parse the jwt token which is in the format 'Bearer '. I believe this is the best approach I can think of, when it comes to token validation. The accepted answer also uses Regex. I don't know why this is down voted even if it has a better regex. – Arvind Jan 17 '18 at 06:06
  • 2
    This is not a good approach at all. JWT tokens can be signed with private/public certificates, which regex won't check against. – sridesmet Apr 16 '18 at 11:49