You need to submit the login credentials (email & password) along with your HTTP POST
request to help identify the User requesting the access token. Otherwise, auth()->user()
is empty, hence the error.
To generate an access token, you need to first authenticate the User.
For example: (Using email
& password
)
- Define your 'access token' route. Notice the use of
->post(...)
instead of ->get(...)
.
File: app/Config/Routes.php
$routes->post('auth/token', '\App\Controllers\Auth\LoginController::accessToken');
- Define your Controller method that will handle the 'access token' generation. Read: Issuing the Tokens
File: app/Controllers/Auth/LoginController.php
<?php
namespace App\Controllers\Auth;
use App\Controllers\BaseController;
class LoginController extends BaseController
{
public function accessToken()
{
// Validate credentials
$rules = [
'email' => [
'label' => 'Auth.email',
'rules' => config('AuthSession')->emailValidationRules,
],
'password' => [
'label' => 'Auth.password',
'rules' => 'required',
],
];
if (!$this->validate($rules)) {
return $this->response
->setJSON(['errors' => $this->validator->getErrors()])
->setStatusCode(422);
}
if (auth()->loggedIn()) {
auth()->logout();
}
// Attempt to login
$result = auth()->attempt([
'email' => $this->request->getPost('email'),
'password' => $this->request->getPost('password')
]);
if (!$result->isOK()) {
return $this->response
->setJSON(['error' => $result->reason()])
->setStatusCode(401);
}
// Generate token and return to client
$token = auth()->user()->generateAccessToken($this->getDeviceName());
return $this->response
->setJSON(['token' => $token->raw_token]);
}
public function getDeviceName()
{
$agent = $this->request->getUserAgent();
if ($agent->isBrowser()) {
$currentAgent = $agent->getBrowser() . ' ' . $agent->getVersion();
} elseif ($agent->isRobot()) {
$currentAgent = $agent->getRobot();
} elseif ($agent->isMobile()) {
$currentAgent = $agent->getMobile();
} else {
$currentAgent = 'Unidentified User Agent';
}
return $agent->getPlatform() . " - " . $currentAgent;
}
}
- Protect your
/api
routes using the $filters
setting on app/Config/Filters.php
. Read: Protecting Routes
- Exclude your 'access token' (
"auth/token"
) route together with all API routes ("api/*"
) from the global "session"
& "toolbar"
filters.
File: app/Config/Filters.php
<?php
// ...
class Filters extends BaseConfig
{
// ...
public array $globals = [
'before' => [
'session' => ['except' => [
"login*",
"register",
"auth/a/*",
"auth/token",
"api/*"
]],
],
'after' => [
'toolbar' => ['except' => ["auth/token", "api/*"]],
],
];
// ...
public array $filters = [
'tokens' => ['before' => ["api/*"]],
];
}
- Make a one-time initial HTTP
POST
request to the auth/token
route to receive the 'access token'. Upon receiving the token, store it with the client. I.e: in localStorage
$.ajax({
url: "https://your-site-domain.com/auth/token",
type: "POST",
data: {
"email": "USER-EMAIL-ADDRESS-HERE",
"password": "USER-PASSWORD-HERE",
},
success: function (response) {
window.localStorage.setItem('token', response.token);
},
error: function (jqXHR) {
console.log(jqXHR.responseText);
},
});
- You may now send the received/stored access token using the
Authorization
header along with all your other protected API HTTP requests in your application without reauthenticating the user. i.e:
$.ajax({
url: "https://your-site-domain.com/api/rest/v1/employees",
type: "GET",
beforeSend: function (jqXHR) {
jqXHR.setRequestHeader(
"Authorization",
"Bearer " + window.localStorage.getItem('token')
);
},
data: {},
success: function (response) {
// Use the response here on success.
// I.e: listing all employees in a table.
},
error: function (jqXHR) {
console.log(jqXHR.responseText);
},
});