diff --git a/INSTRUCTION.md b/INSTRUCTION.md index ddf96c9..b7fef38 100644 --- a/INSTRUCTION.md +++ b/INSTRUCTION.md @@ -5,27 +5,32 @@ Here is an example of using this package to secure your API. This package is a wrapper of the [lcobucci/jwt](https://github.com/lcobucci/jwt) so for the details of using it I recommend reading [its documentation](https://lcobucci-jwt.readthedocs.io/en/latest/). -I'm using here ECDSA asymmetric key with elliptic curve size 256 and a passphrase - the code of this key is `ES256`. +I'm using here ECDSA asymmetric key with elliptic curve size 256 - the code of this key is `ES256`. ## Step 1: Generating the keys On Linux run ```sh -ssh-keygen -t ecdsa -b 256 +openssl ecparam -genkey -name prime256v1 -noout -out private.pem ``` -Enter the folder where you would like your keys to be generated and the name of the key and provide the passphrase -(if you want). In this example I'm using passphrase `stopwars`. -You will get two files - one without an extension which is the private key, and one with `pub` extension which is -the public key (keys are different hence the type - asymmetric). +This creates a file with your private key named `private.pem`. Next run + +```sh +openssl ec -in private.pem -pubout -out public.pem +``` + +You will get a file with your public key named `public.pem`. Private and public keys are different hence the type - +asymmetric. You can name the files differently if you want. + Place the files somewhere where they cannot be accessed through the web (IMPORTANT!) but are still readable by your application. You can place them in your application structure but usually above the `web` or `public` folder - again, it all depends on your server configuration. For other OS please refer to the online guides about generating SSH keys. -## Step 1: Configuration +## Step 2: Configuration Add `jwt` component to your configuration file: @@ -36,13 +41,11 @@ Add `jwt` component to your configuration file: 'class' => \bizley\jwt\Jwt::class, 'signer' => \bizley\jwt\Jwt::ES256, 'signingKey' => [ - 'key' => '', // path to your PRIVATE key, you can start the path with @ to indicate this is a Yii alias - 'passphrase' => 'stopwars', // omit it if you are not adding any passphrase + 'key' => '...', // path to your PRIVATE key, you can start the path with @ to indicate this is a Yii alias 'method' => \bizley\jwt\Jwt::METHOD_FILE, ], 'verifyingKey' => [ // required for asymmetric keys - 'key' => '', // path to your PUBLIC key, you can start the path with @ to indicate this is a Yii alias - 'passphrase' => 'stopwars', // omit it if you are not adding any passphrase + 'key' => '...', // path to your PUBLIC key, you can start the path with @ to indicate this is a Yii alias 'method' => \bizley\jwt\Jwt::METHOD_FILE, ], 'validationConstraints' => static fn (\bizley\jwt\Jwt $jwt) { @@ -69,13 +72,13 @@ Validation constraints used here are: *NOTE*: The above implementation requires to install `lcobucci/clock` library first (run `composer req lcobucci/clock`). If you prefer other PSR-20 clock implementation you must change the above `\Lcobucci\Clock\SystemClock()` usage. -You can also add here any other constraint that you find necessary. The available list is at -https://github.com/lcobucci/jwt/tree/4.1.x/src/Validation/Constraint, and you can always write your own constraint as +You can also add here any other constraint that you find necessary. The available list is at +https://github.com/lcobucci/jwt/tree/5.5.x/src/Validation/Constraint, and you can always write your own constraint as long as it implements `Lcobucci\JWT\Validation\Constraint`. For other ways to add constraints please refer to the README file. -## Step 2: Issuing the token +## Step 3: Issuing the token New access token should be given to the API client after successful authentication, which usually is done through providing valid username and password. I'm assuming you have prepared a controller (or similar) to handle the user input @@ -108,13 +111,13 @@ Now it's a matter of returning this value back to the client, for example: return ['token' => $tokenString]; ``` -## Step 3: Passing the token +## Step 4: Passing the token API client should use the given token and send it with the API requests to authorize the user. In order to do that client must send `Authorization` header with value `Bearer xxx`, where `xxx` is the token string itself. -## Step 4: Validating the token +## Step 5: Validating the token In the API controller we can add authorization filter: diff --git a/tests/data/es256.openssl3.private.pem b/tests/data/es256.openssl3.private.pem new file mode 100644 index 0000000..cd88110 --- /dev/null +++ b/tests/data/es256.openssl3.private.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIJoFx/wz4E3ttFdJ+td1N1mQcQoup5aP3+oZYK70VbBhoAoGCCqGSM49 +AwEHoUQDQgAEy/O5Z7XD44jPzWAOsi3zdU3Aw7IocLxMqVWz+ZM5tWH1ub8G9V55 +tz5/D4gn3a7pcz7Dvrv/hfAMKXvXPL1oLQ== +-----END EC PRIVATE KEY----- diff --git a/tests/data/es256.openssl3.public.pem b/tests/data/es256.openssl3.public.pem new file mode 100644 index 0000000..447dcc9 --- /dev/null +++ b/tests/data/es256.openssl3.public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEy/O5Z7XD44jPzWAOsi3zdU3Aw7Io +cLxMqVWz+ZM5tWH1ub8G9V55tz5/D4gn3a7pcz7Dvrv/hfAMKXvXPL1oLQ== +-----END PUBLIC KEY----- diff --git a/tests/standard/SignerTest.php b/tests/standard/SignerTest.php index 1c21612..1c787cb 100644 --- a/tests/standard/SignerTest.php +++ b/tests/standard/SignerTest.php @@ -175,6 +175,14 @@ public static function providerForSigners(): iterable ], Jwt::ES512 ]; + yield 'OpenSSL3 ES256' => [ + [ + 'signer' => Jwt::ES256, + 'signingKey' => '@bizley/tests/data/es256.openssl3.private.pem', + 'verifyingKey' => '@bizley/tests/data/es256.openssl3.public.pem', + ], + Jwt::ES256 + ]; } #[Attributes\DataProvider('providerForSigners')]