Authenticate stateless with ApiKey Bundle Symfony2

If you want not store authentication in the session and authentication each request, you can follow this post. In this post, I guide you authentication stateless with api key use ApiKey Bundle
ApiKey Bundle is bundle Creates an avenue for using ApiKey authentication for Symfony2. Requires FOSUserBundle.
This bundle follow post: How to Authenticate Users with API Keys and has more useful function. Bundle requires FOSUserBundle.

1. Install

Requires composer
composer require uecode/api-key-bundle dev-master
Enable bundle in AppKernel.php
public function registerBundles()
{
    $bundles = array(
    // ...
    new UecodeBundleApiKeyBundleUecodeApiKeyBundle(),
    );
}

2. Setup entity

If you already have User entity, make this extends class UecodeBundleApiKeyBundleModelApiKeyUser
use UecodeBundleApiKeyBundleModelApiKeyUser;
/**
* @ORMEntity
* @ORMTable(name="user")
*/
class User extends ApiKeyUser
{
    public function __construct()
    {
        parent::__construct();
        $this->setEnabled(true);
    }
    /**
    * @ORMColumn(type="string", length=50, nullable=true)
    * @Groups({"user"})
    */
    private $gender;
}
Try update schema again:
php app/console doctrine:schema:update –force
It will add 1 new column to database: api_key. This column will use to save unique key as user. This key will generate follow function has defined in ApiKeyUser class:

Generates an API Key method

/**
 * Generates an API Key
 */
public function generateApiKey()
{
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $apikey = '';
    for ($i = 0; $i < 64; $i++) {
        $apikey .= $characters[rand(0, strlen($characters) - 1)];
    }
    $apikey = base64_encode(sha1(uniqid('ue' . rand(rand(), rand())) . $apikey));
    $this->apiKey = $apikey;
}
You can override if you want in this User entity.

3. Setup sercurity

In security.yml, change provider to uecode.api_key.provider.user_provider
security:
    providers:
        db:
            id: uecode.api_key.provider.user_provider

Now, you add api_key: true, and stateless: true to firewalls you want authentication with api_key. Ex: in sercurity.yml:
security:
    firewalls:
        auth:
            pattern: ^/api/*
            api_key: true
            stateless: true
Done. You had setup complete authentication with apiKey. So, each request to ^/api/& need has api_key query. Ex:
http://example.com/api/user.json?api_key=OTE2Y2IyMzNhY2ZjZWY3Mjk1MzZkNzQ2YTJlMDhjNDdmNWJiYTg3NQ==
If not has api_key query, it should return 401 response.

Bonus Configure

You can override children path of api, so this path not need api_key for each request. Ex:
security:
    firewalls:
        document:
            pattern: ^/api/doc
            security: false
        auth:
            pattern: ^/api/*
            api_key: true
            stateless: true
So with example, you need api_key query if you request to ^/api/user or ^/api/post,… but not need api_key query if you request to ^/api/doc.
Thank for reading!