chalasr/jwt-user-bundle

Json Web Token authentication bundle including FOSUserBundle integration


Keywords
rest, Symfony2, api, Authentication, user, token, jwt, fosuser, fosrest, lexikjwt
License
GPL-3.0

Documentation

SensioLabsInsight StyleCI Build Status

RCH/JWTUserBundle (v2.x)

Manages users through JSON Web Token in your REST Api.

What's inside

Requirements

  • PHP 5.5+
  • Symfony 3.0+

Note This branch requires friendsofsymfony/user-bundle versions ~2.0.
For using friendsofsymfony/user-bundle versions ~1.3 (>= 1.3, < 2.0), please use the 1.x branch of this bundle.

Installation

1) Download the bundle

Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle:

$ composer require rch/jwt-user-bundle:2.0.x-dev

This command requires you to have Composer installed globally, as explained in the installation chapter of the Composer documentation.

2) Enable the Bundle

Note: This bundle requires 3rd party bundles that need to be registered too.

Then, enable the bundles by adding them to the list of registered bundles in the app/AppKernel.php file of your project:

// app/AppKernel.php

<?php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new RCH\JWTUserBundle\RCHJWTUserBundle(),
            new FOS\UserBundle\FOSUserBundle(),
            new Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle(),
            new Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle(),
        );

        // ...
    }

    // ...
}

Configuration

1) Create your User class

Your user class needs to extend the RCH\JWTUserBundle\Entity\User MappedSuperclass.

Example:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use RCH\JWTUserBundle\Entity\User as BaseUser;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
}

2) Set the bundle configuration

Configure it:

# app/config/config.yml
rch_jwt_user:
    user_class: AppBundle\Entity\User # your user class (required)
    user_identity_field: email        # the property used as authentication credential (tied to password)
    passphrase: foobar                # the passphrase of your RSA private key

Load the routing:

# app/config/routing.yml
rch_jwt_user:
    resource: "@RCHJWTUserBundle/Resources/config/routing.yml"
    # Set a prefix if you want i.e. prefix: /api

Set the security config accordingly, example:

security:
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email

    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        # Signin
        login:
            pattern:  ^/login
            stateless: true
            anonymous: true
            form_login:
                provider: fos_userbundle
                check_path: /login
                require_previous_session: false
                username_parameter: email
                password_parameter: password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure
        # Signup
        register:
            pattern: ^/register
            anonymous: true
            stateless: true
        # Refresh token
        refresh:
            pattern:  ^/refresh_token
            stateless: true
            anonymous: true
        # API (secured via JWT)
        api:
            pattern:   ^/
            stateless: true
            lexik_jwt: ~

    access_control:
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/refresh_token, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, role: IS_AUTHENTICATED_FULLY }

3) Generate RSA keys for signing/verifying JWT tokens

$ php bin/console rch:jwt:generate-keys

Note This command generates keys using the configured passphrase.

Usage

Register users via the /register route:

$ curl -X POST http://localhost:8000/register -d username=johndoe -d password=test

Get a JWT token via the /login route:

$ curl -X POST http://localhost:8000/login -d username=johndoe -d password=test

Refresh the token once it expires via the /refresh_token route:

$ curl -X POST http://localhost:8000/refresh_token -d token=[the expired token] -d refresh_token=[the refresh_token]

Use the token to access secured resources:

$ curl -H "Authorization: Bearer [token here]" http://localhost:8000

Note The refresh token is provided in the response of a successful login, in the same time as you get the token.

Note2 Each time username is used in the previous examples, it must be replaced by the username_parameter value, set into the secured firewall's mapping.

Note3 For the password field, it must be replaced by the password_parameter value.

Contributing

See the contribution guidelines in the CONTRIBUTING.md distributed file.

Troubleshooting

This bundle includes a set of third party dependencies, its stability mostly depends on these ones.

If you are facing problems in its installation/usage, please open an issue on this repository.

License

The code is released under the GPL-3.0 license.

For the whole copyright, see the LICENSE file.