How to properly use Bearer tokens?
Asked Answered
P

3

62

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
Pandich answered 14/11, 2016 at 5:3 Comment(0)
P
187

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;
}
Pickaxe answered 14/11, 2016 at 5:39 Comment(11)
It's a nice function, you have suggested, but the $headers I am returning, It will have, say: Bearer <space> <AuthToken> so now, is it right to just explode the string by space and take the actual token, or the full string (Bearer <space> <token>) is supposed to be taken as a whole?Pandich
<AuthToken> that's right. You can explode by space.Pickaxe
I missed a function. XDPickaxe
can you please add setBearerToken function??Ornithopod
I'd just use a substr() to get the actual token but not the bearer. Should be much faster than preg_match().Silvas
You don't need a setBearerToken() function. Just use this line: header('Authorization: Bearer TOKEN'); // Replace TOKEN with the appropriate JWT stringStudnia
And how to send bearer auth info with php curl?Seda
Can you help for this? #58582068Seda
@Seda look at getAuthorizationHeader function Auth token can be store in Authorization, HTTP_AUTHORIZATION or 'apache_request_headers' function that base on your server version.Pickaxe
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.Seda
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 }Lindseylindsley
L
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/

Lifesaver answered 23/3, 2017 at 18:15 Comment(3)
Regex is not always the recommend approach for parsing string unless you can't acheive with the existing PHP String functions.Piece
Regex is used to find patterns. Imo, you can use regex to parse the jwt token which is in the format 'Bearer <token>'. 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.Mukul
This is not a good approach at all. JWT tokens can be signed with private/public certificates, which regex won't check against.Alternant
A
0

The function searches for the header and removes the Bearer prefix:

    private function getBearerToken(): ?string
    {
        $headers = array_change_key_case(getallheaders(), CASE_LOWER);
        if (!isset($headers['authorization'])) {
            return null;
        }

        return trim(str_replace('Bearer', '', $headers['authorization']));
    }
Antemortem answered 12/12, 2023 at 17:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.