Skip to content

Instantly share code, notes, and snippets.

@johnpancoast
Last active March 9, 2017 04:57
Show Gist options
  • Save johnpancoast/1a2c676a1d7fa26c88c078bd6beccd03 to your computer and use it in GitHub Desktop.
Save johnpancoast/1a2c676a1d7fa26c88c078bd6beccd03 to your computer and use it in GitHub Desktop.
Command to automatically create JWT keys required by LexikJWTAuthenticationBundle
<?php
namespace My\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
/**
* Command to automatically create the JWT keys necessary for token creation and validation.
*
* @author John Pancoast <johnpancoaster@gmail.com>
* @see https://github.com/lexik/LexikJWTAuthenticationBundle
*/
class CreateJwtKeysCommand extends ContainerAwareCommand
{
/**
* @inheritDoc
*/
protected function configure()
{
$this
->setName('app:create-jwt-keys')
->setDescription(
'Create JWT keys necessary for JWT token creation (required by LexikJWTAuthenticationBundle).'
)
->addOption(
'force',
'f',
InputOption::VALUE_NONE,
'Force recreation of keys'
)
;
}
/**
* @inheritDoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$fs = new Filesystem();
$prvKeyPath = $this->getContainer()->getParameter('jwt_private_key_path');
$pubKeyPath = $this->getContainer()->getParameter('jwt_public_key_path');
$pass = $this->getContainer()->getParameter('jwt_key_pass_phrase');
if (($fs->exists($prvKeyPath) || $fs->exists($pubKeyPath)) && !$input->getOption('force')) {
$io->caution('This will recreate JWT keys used for token creation which will invalidate all issued JWT tokens. This means all users will be required to login again.');
$response = strtolower($io->ask('Are you sure you want to do this?'));
if ($response != 'y' && $response != 'yes') {
$io->writeln('Exiting...');
return;
}
}
try {
$sslCmd = trim((new Process('which openssl'))->mustRun()->getOutput());
} catch (\Exception $e) {
throw new \RuntimeException(
sprintf(
'Command requires openssl',
$this->getName()
)
);
}
$io->writeln('<info>(re)creating JWT private key</info>');
// mkdir then write private key, pass the password to the command's stdin so the password isn't shown in ps.
(new Process(
sprintf(
'/bin/mkdir -p %s && %s genrsa -passout stdin -out %s -aes256 4096',
dirname($prvKeyPath),
$sslCmd,
$prvKeyPath
)
))->setInput($pass)->mustRun();
$io->writeln('<info>(re)creating JWT public key</info>');
// mkdir then write public key, pass the password to the command's stdin so the password isn't shown in ps.
(new Process(
sprintf(
'/bin/mkdir -p %s && %s rsa -passin stdin -pubout -in %s -out %s',
dirname($pubKeyPath),
$sslCmd,
$prvKeyPath,
$pubKeyPath
)
))->setInput($pass)->mustRun();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment