Are there any JWT authenticator example? I don’t understand documentation clearly.
I need also an example! I’m in you opinion that the documentation is not clear enough! I hope you get an answer!
Someone please help us…on JWT
You follow the getting started by attaching the middleware and return a configured service in Application::getAuthenticationService
. Configure JWT with JWT Authenticator and the JWT Subject identifier.
Here’s an example:
@Schlaefer I’ve implemented the same way you mentioned. Authentication and token generation is working fine but it doesn’t return user data when accessing it using $this->Authentication->getIdentity();
.
Is there anything special we have to do in order to set user data?
$id = $this->Authentication->getIdentityData(‘id’);
In order get authenticated user’s data, you just have to set returnPayload
option to false
in your src/Application.php
file where you’ve load JWT authenticator.
The reason behind is clearly mentioned in documentation, if we set returnPayload
option to true
it will return the token payload directly without going through the JWT Subject Identifier set in Application.php
file.
Please find this project as a proof of concept.
I need help! (FIXED)
CakePHP 4.2.3
I implemented the code as above, but it still returns an error message and asks for authorization on methods other than login and register.
I’m trying via postman to send a get request with a token query, or as a header as written in the documentation, but I’m out of luck.
Here is my code:
Application.php
public function getAuthenticationService(ServerRequestInterface $request): AuthenticationServiceInterface
{
$service = new AuthenticationService();
$fields = [
IdentifierInterface::CREDENTIAL_USERNAME => 'email',
IdentifierInterface::CREDENTIAL_PASSWORD => 'password',
];
// $service->loadAuthenticator('Authentication.Token', [
// 'queryParam' => 'token',
// 'header' => 'Authorization',
// 'tokenPrefix' => 'Bearer',
// ]);
// Load the authenticators.
$service->loadAuthenticator('Authentication.Jwt', [
'secretKey' => Security::getSalt(),
'returnPayload' => false,
'queryParam' => 'token',
// 'header' => 'Authorization',
// 'tokenPrefix' => 'Bearer',
]);
$service->loadAuthenticator('Authentication.Form', [
'fields' => $fields,
]);
// Load identifiers
$service->loadIdentifier('Authentication.JwtSubject');
$service->loadIdentifier('Authentication.Password', [
'returnPayload' => false,
'fields' => $fields,
]);
return $service;
}
Users class
class UsersController extends AppController
{
/**
* @inheritDoc
*/
public function beforeFilter(\Cake\Event\EventInterface $event)
{
parent::beforeFilter($event);
// Configure the login action to not require authentication, preventing
// the infinite redirect loop issue
$this->Authentication->addUnauthenticatedActions([
'login',
'register',
]);
}
/**
* Index method
*
* @return \Cake\Http\Response|null|void Renders view
*/
public function index()
{
$this->paginate = [
'contain' => ['Companies'],
];
$users = $this->paginate($this->Users);
$this->set('users', $users);
$this->viewBuilder()->setOption('serialize', ['users']);
}
/**
* Users Login
*
* @return \Cake\Http\Response|null|void
*/
public function login()
{
$this->request->allowMethod(['get', 'post']);
$result = $this->Authentication->getResult();
if ($result->isValid()) {
$user = $result->getData();
$payload = [
'sub' => $user->id,
'exp' => time() + 60,
];
$json = [
'token' => JWT::encode($payload, Security::getSalt(), 'HS256'),
];
} else {
$this->response = $this->response->withStatus(401);
$json = [];
}
$this->set(compact('json'));
$this->viewBuilder()->setOption('serialize', 'json');
}
/**
* Register method
*
* @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
*/
public function register()
{
$user = $this->Users->newEmptyEntity();
$message = null;
if ($this->getRequest()->is(['post', 'put'])) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$message = __('The user has been saved.');
} else {
$message = __('The user could not be saved. Please, try again.');
}
}
$this->set(compact('user', 'message'));
$this->viewBuilder()->setOption('serialize', ['user', 'message']);
}
I successfully register a new user, also the login returns the token, but when I visit for example http://localhost/users.json?token= TOKEN_HERE
{
"message": "Authentication is required to continue",
"url": "/users.json?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.........",
"code": 401,
"file": "/app/vendor/cakephp/authentication/src/Controller/Component/AuthenticationComponent.php",
"line": 177
}
Fixed
login action:
'exp' => time() + 604800,
and
$service->loadAuthenticator('Authentication.Jwt', [
'secretKey' => Security::getSalt(),
'queryParam' => 'token',
'header' => 'Authorization',
'tokenPrefix' => 'Bearer', // postman sends a tokenPrefix Bearer with the first capital letter
'returnPayload' => false,
]);
FWIW there are plugins available for this too: