Search code examples
laravelapiauthenticationaccess-token

Problem getting a new token after expiry time lapses in token-based authentication in Laravel


Working on a Laravel application whereby I am performing authentication to an API that requires token to be passed during login and subsequent requests must be passed using a token. The login logic is working fine.

I am having a problem implementing a functionality whereby after the expiry time lapses the user should be redirected to login page to login again so that a new token is issued.

~ Please assist?

Login Logic

public function login(Request $request){ 
    try {

        $username = $request['user'];
        $access_type = GeneralHelper::checkInput($username);

        //Data to the passed to the API
        $data = array(
            $access_type => $username,
            'password' => $request['password'],
            'login_type' => $access_type,
            'access_type' => 'web',
        );

        //Hit teh API and get a response
        $loginstatus = GeneralHelper::login_Curl($data, 'api/v1/auth/login');

        //Get the response which is success in this case
        $res_status = $loginstatus->status;

        //If suucess is true put some data in a session
        if ($res_status == 'success') {
            Session::put('user', $loginstatus->data->user);
            Session::put('access_token', $loginstatus->data->access_token);
            Session::put('refresh_token', $loginstatus->data->refresh_token);
            Session::put('expiry', $loginstatus->data->expires_in);

        } elseif ($res_status == 'failure') {
            return redirect('/login')->with('error', $loginstatus->message);
        }
    } catch (\Exception $e) {
        return $e->getMessage() . "\n at LINE " . $e->getLine();
    }

}

Function to check the if token is available

 public function checkAccessToken(){
        //Return true if token is available
        if(!is_null(session('access_token'))){
            return true;
        }
        else {
             return false;
        }
    }

Sample Response am getting from the API after hitting it

{
    "request_time": "2018-12-10 13:36:19",
    "response_time": "2018-12-10 13:36:19",
    "status": "success",
    "message": "login",
    "data": {
        "token_type": "Bearer",
        "expires_in": 3600,
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUz******************",
        "refresh_token": "def5020018e6345ab78d32*********************",
        "isAgent": true,
        "user": {
            "firstname": "*************",
            "middlename": "*************",
            "surname": "************",
            "phone": "25***********",
            "email": "*************",
            "tax_id": "************",
            "passport_no": null,
            "national_id": "***********",
            "dob": null
        }
    }
}

checkAccessToken function

public function getLifePolicies(){
        if(!$this->checkAccessToken()){
            return redirect('/')->with('error','Your session has expired. Please Login again');
        }

        else{
            //Perform other action

        }
    }

Solution

  • I am having a problem implementing a functionality whereby after the expiry time lapses the user should be redirected to login page to login again so that a new token is issued.

    When you do if elseif block you need to do instead a if else block so that you always reach the redirection to the login page.

    //If suucess is true put some data in a session
    if ($res_status === 'success') {
        Session::put('user', $loginstatus->data->user);
        Session::put('access_token', $loginstatus->data->access_token);
        Session::put('refresh_token', $loginstatus->data->refresh_token);
        Session::put('expiry', $loginstatus->data->expires_in);
    
    } else {
        return redirect('/login')->with('error', $loginstatus->message);
    }
    

    Best practice note

    Always use strict comparison in PHP === instead of weak comparison ==.

    Security Note

    From a security point of view this is not recommended:

    return $e->getMessage() . "\n at LINE " . $e->getLine();
    

    The $e->getMessage() may reveal sensitive information about your application. Instead you should log that information and return a generic phrase that does not leak any potential information to a potential attacker.