-
-
Notifications
You must be signed in to change notification settings - Fork 610
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Nicolas Cabot
committed
Jul 15, 2014
1 parent
1dce62e
commit a066b42
Showing
7 changed files
with
409 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Contributing | ||
============ | ||
|
||
First of all, **thank you** for contributing, **you are awesome**! | ||
|
||
Here are a few rules to follow in order to ease code reviews, and discussions before | ||
maintainers accept and merge your work. | ||
|
||
You MUST follow the [PSR-1](http://www.php-fig.org/psr/1/) and | ||
[PSR-2](http://www.php-fig.org/psr/2/). If you don't know about any of them, you | ||
should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer | ||
tool](http://cs.sensiolabs.org/). | ||
|
||
You MUST run the test suite. | ||
|
||
You MUST write (or update) unit tests. | ||
|
||
You SHOULD write documentation. | ||
|
||
Please, write [commit messages that make | ||
sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), | ||
and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing) | ||
before submitting your Pull Request. | ||
|
||
One may ask you to [squash your | ||
commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html) | ||
too. This is used to "clean" your Pull Request before merging it (we don't want | ||
commits such as `fix tests`, `fix 2`, `fix 3`, etc.). | ||
|
||
Thank you! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,201 +5,43 @@ LexikJWTAuthenticationBundle | |
[![Latest Stable Version](https://poser.pugx.org/lexik/jwt-authentication-bundle/v/stable.svg)](https://packagist.org/packages/lexik/jwt-authentication-bundle) | ||
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/67573b6f-e182-4394-b26a-649c323784f6/mini.png)](https://insight.sensiolabs.com/projects/67573b6f-e182-4394-b26a-649c323784f6) | ||
|
||
This bundle provides JWT (Json Web Token) authentication for your Symfony2 REST API using the [`namshi/jose`](https://github.com/namshi/jose) library. | ||
|
||
This bundle provides JWT (Json Web Token) authentication for your Symfony2 REST API using the great [`namshi/jose`](https://github.com/namshi/jose) library. | ||
It has been tested using PHP5.3 to PHP5.6 and HHVM, and Symfony2.3 to Symfony2.5. | ||
|
||
Installation | ||
Documentation | ||
------------- | ||
|
||
The bulk of the documentation is stored in the `Resources/doc/index.md` file in this bundle: | ||
|
||
[Read the documentation](Resources/doc/index.md) | ||
|
||
Testing | ||
------- | ||
|
||
Setup the test suite using [Composer](http://getcomposer.org/): | ||
|
||
$ composer install --dev | ||
|
||
Run it using PHPUnit: | ||
|
||
$ bin/phpunit | ||
|
||
Contributing | ||
------------ | ||
|
||
Require [`lexik/jwt-authentication-bundle`](https://packagist.org/packages/lexik/jwt-authentication-bundle) | ||
into your `composer.json` file: | ||
|
||
``` json | ||
{ | ||
"require": { | ||
"lexik/jwt-authentication-bundle": "@stable" | ||
} | ||
} | ||
``` | ||
|
||
**Protip:** you should browse the | ||
[`lexik/jwt-authentication-bundle`](https://packagist.org/packages/lexik/jwt-authentication-bundle) | ||
page to choose a stable version to use, avoid the `@stable` meta constraint. | ||
|
||
Register the bundle in `app/AppKernel.php`: | ||
|
||
``` php | ||
// app/AppKernel.php | ||
public function registerBundles() | ||
{ | ||
return array( | ||
// ... | ||
new Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle(), | ||
); | ||
} | ||
``` | ||
|
||
Configuration | ||
------------- | ||
See [CONTRIBUTING](CONTRIBUTING.md) file. | ||
|
||
|
||
Credits | ||
------- | ||
|
||
* Lexik <[email protected]> | ||
* [All contributors](https://github.com/lexik/LexikJWTAuthenticationBundle/graphs/contributors) | ||
|
||
License | ||
------- | ||
|
||
This bundle is under the MIT license. See the complete license in the bundle: | ||
|
||
Please read the [namshi/jose library](https://github.com/namshi/jose) documentation first. | ||
|
||
First, generate the keys used for token generation (for example) : | ||
|
||
``` bash | ||
$ openssl genrsa -out app/var/jwt/private.pem -aes256 4096 | ||
$ openssl rsa -pubout -in app/var/jwt/private.pem -out app/var/jwt/public.pem | ||
``` | ||
|
||
Then in your `config.yml` : | ||
|
||
``` yaml | ||
lexik_jwt_authentication: | ||
private_key_path: %kernel.root_dir%/var/jwt/private.pem # path to the private key | ||
public_key_path: %kernel.root_dir%/var/jwt/public.pem # path to the public key | ||
pass_phrase: '' # optional - pass phrase, defaults to '' | ||
token_ttl: 86400 # optional - token ttl, defaults to 86400 | ||
``` | ||
Usage | ||
----- | ||
First of all, you need to authenticate the user using its credentials through form login. | ||
Set the `lexik_jwt_authentication.handler.authentication_success` service as success handler, which will generate the JWT token and send it as the body of a JsonResponse. | ||
|
||
Store the token in your client application (using cookie, localstorage or whatever - the token is encrypted). | ||
Now, you only need to pass the token on each future request, either as an authorization header or as a query string parameter. | ||
|
||
If it results in a 401 response, your token is invalid (most likely its ttl has expired - 86400 seconds by default). | ||
Redo the authentication process to get a fresh token. | ||
|
||
### Example of possible `security.yml` : | ||
|
||
``` yaml | ||
firewalls: | ||
# used to authenticate the user the first time with its username and password, using form login | ||
login: | ||
pattern: ^/api/login | ||
stateless: true | ||
anonymous: true | ||
form_login: | ||
check_path: /api/login_check | ||
require_previous_session: false | ||
username_parameter: username | ||
password_parameter: password | ||
success_handler: lexik_jwt_authentication.handler.authentication_success # generate the jwt token and send it as 200 response body | ||
failure_handler: lexik_jwt_authentication.handler.authentication_failure # send a 401 response | ||
# protected firewall, where a user will be authenticated by its jwt token | ||
api: | ||
pattern: ^/api | ||
stateless: true | ||
# default configuration | ||
lexik_jwt: ~ # check token in Authorization Header, with a value prefix of 'Bearer' | ||
# advanced configuration | ||
lexik_jwt: | ||
authorization_header: # check token in Authorization Header | ||
enabled: true | ||
prefix: Bearer | ||
query_parameter: # check token in query string parameter | ||
enabled: true | ||
name: bearer | ||
throw_exceptions: false # When an authentication failure occurs, return a 401 response immediately | ||
create_entry_point: true # When no authentication details are provided, create a default entry point that returns a 401 response | ||
access_control: | ||
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } | ||
- { path: ^/api, roles: ROLE_USER } | ||
``` | ||
|
||
### Add extra data to response (example) | ||
|
||
If you need to send some extra data (not encrypted) to your client, let's say the user roles or name, you can do that by listening to the lexik_jwt_authentication.on_authentication_success event. | ||
|
||
For example : | ||
|
||
In your `services.yml` : | ||
|
||
``` yaml | ||
acme_user.event.authentication_success_listener: | ||
class: Acme\Bundle\UserBundle\EventListener\AuthenticationSuccessListener | ||
tags: | ||
- { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthenticationSuccessResponse } | ||
``` | ||
|
||
In your `AuthenticationSuccessListener.php` : | ||
|
||
``` php | ||
/** | ||
* @param AuthenticationSuccessEvent $event | ||
*/ | ||
public function onAuthenticationSuccessResponse(AuthenticationSuccessEvent $event) | ||
{ | ||
$data = $event->getData(); | ||
$user = $event->getUser(); | ||
if (!$user instanceof \Acme\Bundle\UserBundle\Entity\User) { | ||
return; | ||
} | ||
$data['profile'] = [ | ||
'firstname' => $user->getFirstName(), | ||
'lastname' => $user->getLastName(), | ||
'roles' => $user->getRoles(), | ||
]; | ||
$event->setData($data); | ||
} | ||
``` | ||
|
||
### Using jwt authentication in functional tests | ||
|
||
Generate some test specific keys, for example : | ||
|
||
``` bash | ||
$ openssl genrsa -out app/cache/test/jwt/private.pem -aes256 4096 | ||
$ openssl rsa -pubout -in app/cache/test/jwt/private.pem -out app/cache/test/jwt/public.pem | ||
``` | ||
|
||
Override the bundle configuration in your `config_test.yml` : | ||
|
||
``` yaml | ||
lexik_jwt_authentication: | ||
private_key_path: %kernel.cache_dir%/jwt/private.pem | ||
public_key_path: %kernel.cache_dir%/jwt/jwt/public.pem | ||
``` | ||
|
||
In your functional tests, create an authenticated client : | ||
|
||
``` php | ||
/** | ||
* Create a client with a default Authorization header. | ||
* | ||
* @param string $username | ||
* @param string $password | ||
* | ||
* @return \Symfony\Bundle\FrameworkBundle\Client | ||
*/ | ||
protected function createAuthenticatedClient($username = 'user', $password = 'password') | ||
{ | ||
$client = static::createClient(); | ||
$client->request( | ||
'POST', | ||
'/login_check', | ||
array( | ||
'username' => $username, | ||
'password' => $password, | ||
) | ||
); | ||
$response = $client->getResponse(); | ||
$data = json_decode($response->getContent(), true); | ||
$client = static::createClient(); | ||
$client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $data['token'])); | ||
return $client; | ||
} | ||
``` | ||
Resources/meta/LICENSE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Configuration reference | ||
======================= | ||
|
||
#### Simplest configuration | ||
|
||
``` yaml | ||
# ... | ||
firewalls: | ||
# ... | ||
api: | ||
# ... | ||
lexik_jwt: ~ # check token in Authorization Header, with a value prefix of 'Bearer' | ||
``` | ||
#### Full configuration | ||
``` yaml | ||
# ... | ||
firewalls: | ||
# ... | ||
api: | ||
# ... | ||
# advanced configuration | ||
lexik_jwt: | ||
authorization_header: # check token in Authorization Header | ||
enabled: true | ||
prefix: Bearer | ||
query_parameter: # check token in query string parameter | ||
enabled: true | ||
name: bearer | ||
throw_exceptions: false # When an authentication failure occurs, return a 401 response immediately | ||
create_entry_point: true # When no authentication details are provided, create a default entry point that returns a 401 response | ||
``` |
Oops, something went wrong.