Api Tokens
Forme provides a basic way to generate and validate authentication tokens. This is useful for situations where you want to provide authentication for an API, for example for a single page app.
Generating a Token
To generate a new authentication token, you can use the get
method of the Forme\Framework\Auth\Token
class. This method takes a name
argument, which is a unique identifier for the token. It returns the generated token as a string.
$token = Forme\getInstance(Token::class)->get('my-unique-token-name');
Validating a Token
To validate an authentication token, you can use the validate
method of the Forme\Framework\Auth\Token
class. This method takes two arguments: the token
string to be validated, and the name
that the token was generated with. It returns true
if the token is valid, and false
if it is not.
$isValid = Forme\getInstance(Token::class)->validate($token, 'my-unique-token-name');
Destroying Tokens
When the get
or validate
methods are called, any expired tokens are automatically purged from the database.
If you need to expire a token before the expiry time, you can destroy it by name.
Forme\getInstance(Token::class)->destroy('my-unique-token-name');
Custom Expiry Time
Forme's authentication tokens have a default expiry time of 2 hours from the time they are generated. If you need a custom expiry time you can set it when you get the token string initially. The expiry parameter should be something that Carbon can parse.
$token = Forme\getInstance(Token::class)->get('my-unique-token-name', '+6 hours');
WARNING
If an unexpired token already exists for this name, setting a new expiry time won't affect that one, only new ones. You would need to explicitly destroy it if you need to invalidate it.
Example Usage
Here is an example of how you might use Forme's authentication tokens in a simple/naive API.
// generate a new token string
$token = Forme\getInstance(Token::class)->get('my-unique-token-name');
// in your API route:
// validate the token string
$isValid = Forme\getInstance(Token::class)->validate($_GET['token_string'], 'my-unique-token-name');
// if the token string is valid, return the requested data
if ($isValid) {
echo json_encode(['data' => 'my-secret-data']);
} else {
// if the token is not valid, return an error
echo json_encode(['error' => 'Invalid token']);
}
In real world use cases, you'll probably want to encode the current user id into the token name so that you can match it up and pass it into the frontend using wp_localize_script
- a good place to do this is probably in your theme or plugin's PublicQueueRegistry
or AdminQueueRegistry
class.
Here is an example of how you might do this in your PublicQueueRegistry
class:
public function register(): void
{
...
// generate a new token for the current user
$token = (Forme\getInstance(Token::class))->get('my-plugin-user-' . get_current_user_id());
// pass the token to the frontend
wp_localize_script('my-plugin-public-scripts', 'authToken', $token);
// enqueue your scripts and styles
wp_enqueue_style('my-plugin-public-styles', Assets::uri('app.css'), [], Assets::time('app.css'));
wp_enqueue_script('my-plugin-public-scripts', Assets::uri('app.js'), ['jquery'], Assets::time('app.js'), true);
}
In your frontend code, you can then access the token string using the authToken
variable, and include it in any API requests to your backend which should then confirm that the current user is authenticated using the above validate
method.
It's up to you to implement this within your controllers and/or PSR 15 middleware - here is an example for the latter:
...
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// get the token from the request
$token = $request->input('token') ?? null;
// get the user id from the request
$userId = $request->input('userId') ?? null;
// validate the token
$isValid = (Forme\getInstance(Token::class))->validate($token, 'my-plugin-user-'.$userId);
if ($isValid) {
// if the token is valid, pass the request on to the next middleware
return $handler->handle($request);
}
// if the token is not valid, return an error response
return new JsonResponse(['error' => 'Invalid token'], 403);
}
}