This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

How to Create Token Based API Authentication in Symfony

Updated on September 14, 2025

5 Min Read
How to Create Token Based API Authentication in Symfony

Key Takeaways

  • Token-based authentication secures API endpoints in Symfony.
  • Symfony Guard simplifies Symfony user authentication and credentials handling.
  • User providers are essential for linking API tokens to users.
  • Firewalls and services configuration complete the authentication workflow.
  • Test API authentication using headers with your API token.

In the prior installment of this series, I wrote about creating a REST API in Symfony. I used HTTP codes with API responses and threw exceptions on bad response codes.

ow, let’s dive deeper into Symfony authentication by implementing token-based API authentication. Using Symfony Guard, you can efficiently handle Symfony user authentication via API tokens, securing your endpoints while simplifying user management. This approach works seamlessly with Symfony 3 authentication and modern Symfony applications, providing a robust solution for API security.

How to Authenticate Users via API Token(s)

We will learn to work with Guard and authenticate users via API token(s). I assume that you have already launched a PHP stack server and application on Cloudways, which is widely known for its best PHP hosting. For help on this prerequisite, check out this guide on installing Symfony on Cloudways.

1) Create a User Class & Provider

To start user authentication in Symfony, I must create a user entity class that implements UserInterface and a user provider. Symfony authentication process depends on the UserProvider. When the user hits the submit button, the user-provider values are checked. After this, further verification of the password takes place.

Following is the entity code:

<?php

namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**

* @ORM\Entity

* @ORM\Table(name="user")

*/

class User implements UserInterface

{

   /**

    * @ORM\Id

    * @ORM\GeneratedValue

    * @ORM\Column(type="integer")

    */

   private $id;

   /**

    * @ORM\Column(type="string", unique=true)

    */

   private $username;

   /**

    * @ORM\Column(type="string", unique=true)

    */

   private $email;

   /**

    * @ORM\Column(type="string")

    */

   private $password;

   /**

    * @ORM\Column(type="json_array")

    */

   private $roles = array();

   /**

    * @ORM\Column(type="string", unique=true)

    */

   private $apiToken;

   public function getId()

   {

       return $this->id;

   }

   public function getUsername()

   {

       return $this->username;

   }

   public function setUsername($username)

   {

       $this->username = $username;

   }

   public function getEmail()

   {

       return $this->email;

   }

   public function setEmail($email)

   {

       $this->email = $email;

   }

   public function getPassword()

   {

       return $this->password;

   }

   public function setPassword($password)

   {

       $this->password = $password;

   }

   /**

    * Returns the roles or permissions granted to the user for security.

    */

   public function getRoles()

   {
       $roles = $this->roles;

       // guarantees that a user always has at least one role for security

       if (empty($roles)) {

           $roles[] = 'ROLE_USER';

       }

       return array_unique($roles);

   }

   public function setRoles($roles)

   {
       $this->roles = $roles;

   }

   /**

    * Returns the salt that was originally used to encode the password.

    */

   public function getSalt()

   {
       return;

   }

   /**

    * Removes sensitive data from the user.

    */

   public function eraseCredentials()

   {

       // if you had a plainPassword property, you'd nullify it here

       // $this->plainPassword = null;

   }

   /**

    * @param string $apiToken

    */

   public function setApiToken($apiToken)

   {

       $this->apiToken = $apiToken;

   }

}

First PHP Website Migration Is Free At Cloudways

Cloudways Engineers can migrate your website Flawlessly

2) Register the Provider in security.yml

The next step is registering the above-made user provider in the security.yml file. To do that, add the following code:

providers:

       api_key_user_provider:

           entity:

               class: AppBundle:User

               property: apikey

I have done it here now. Before creating an authenticator class, let’s install Guard first.

3) Symfony Guard Component

Guard authentication was first introduced in Symfony 2.8 and has become part of Symfony core. Guard provides different layers of Symfony 3 authentication. With Guard, every Symfony authentication process is handled by only one class: an Authenticator. This class will have to implement the provided GuardAuthenticatorInterface.

However, Composer is still the preferred way to install Guard in Symfony. Install with the following command:

$ composer require symfony/security-guard

4) Creating An Authenticator Class

An authenticator class is needed to implement the GuardAuthenticatorInterface and extend the AbstractGuardAuthenticator. This class will read the API token in the header request and find the respective user. Create a new file: src/AppBundle/Security/TokenAuthenticator.php

namespace AppBundle\Security;



use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;


class TokenAuthenticator extends AbstractGuardAuthenticator

{

   /**
    * Called on every request. Return whatever credentials you want to
    * be passed to getUser(). Returning null will cause this authenticator
    * to be skipped.
    */

   public function getCredentials(Request $request)

   {
       if (!$token = $request->headers->get('X-AUTH-TOKEN')) {

           // No token?

           $token = null;

       }

       // What you return here will be passed to getUser() as $credentials

       return array(

           'token' => $token,

       );

   }

   public function getUser($credentials, UserProviderInterface $userProvider)

   {
       $apikey = $credentials['token'];

       if (null === $apikey) {

           return;

       }
       // if null, authentication will fail

       // if a User object, checkCredentials() is called

       return $userProvider->loadUserByUsername($apikey);

   }

   public function checkCredentials($credentials, UserInterface $user)

   {
       // check credentials - e.g. make sure the password is valid

       // no credential check is needed in this case



       // return true to cause authentication success

       return true;

   }

   public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)

   {

       // on success, let the request continue

       return null;

   }

   public function onAuthenticationFailure(Request $request, AuthenticationException $exception)

   {

       $data = array(

           'message' => strtr($exception->getMessageKey(), $exception->getMessageData())

           // or to translate this message

           // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())

       );

       return new JsonResponse($data, Response::HTTP_FORBIDDEN);

   }

   /**

    * Called when authentication is needed, but it's not sent

    */

   public function start(Request $request, AuthenticationException $authException = null)

   {
       $data = array(

           // you might translate this message

           'message' => 'Authentication Required'

       );

       return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);

   }

   public function supportsRememberMe()

   {
       return false;

   }

}

The authentication methods are explained in the comments, but if you want to learn more about the Guard authentication method, you can learn about it on the Symfony documentation page.

5) Configuring The Authenticator

configure the authenticator, I need to update the firewall:

security:
   # ...
   firewalls:
       # ...
       main:
           anonymous: ~
           logout: ~
           guard:
               authenticators:
                   - AppBundle\Security\TokenAuthenticator

After that, register the authenticator as a service in service.yml:

services:
   api_key_authenticator:
       class: AppBundle\Security\TokenAuthenticator
       arguments: ["@router"]

That’s it finally, everything is done now. To check the response, you can use curl to request it.

 curl -H "X-AUTH-TOKEN: username" http://your_app_url

You will be authenticated and redirected to the homepage.

You might also like How To Implement User Authentication In Symfony Using Auth0

Final Words

Using Symfony Guard for token-based authentication allows you to secure your APIs without the complexity of traditional authentication methods. By following this guide, you can implement Symfony user authentication with API tokens, ensuring your endpoints remain safe, scalable, and easy to manage.

Whether you’re using Symfony 3 authentication or newer Symfony versions, this approach streamlines the authentication process and boosts API security.

If you have any questions or queries, you can comment below.

Frequently Asked Questions

1. How do I implement token-based authentication in Symfony?
Use Symfony Guard to create an authenticator class, link it to a user provider, and configure firewalls and services to handle token verification.

2. What is Symfony Guard?
Symfony Guard is a security bundle that simplifies authentication, allowing you to create custom login mechanisms, including token-based and API key authentication.

3. How do I authenticate API requests in Symfony?
Include a valid API token in the request headers and use a Guard authenticator to validate the token against the user provider.

4. Can I use Symfony Guard with Symfony 3 authentication?
Yes, Symfony Guard is fully compatible with Symfony 3 authentication and provides a modern way to handle token-based user authentication.

5. What is the best method for Symfony API authentication?
Token-based authentication via Symfony Guard is recommended for REST APIs, providing secure, scalable, and straightforward user authentication.

Share your opinion in the comment section. COMMENT NOW

Share This Article

Shahzeb Ahmed

Shahzeb is a Digital Marketer with a Software Engineering background, works as a Community Manager — PHP Community at Cloudways. He is growth ambitious and aims to learn & share information about PHP & Laravel Development through practice and experimentation. He loves to travel and explore new ideas whenever he finds time. Get in touch with him at [email protected]

×

Webinar: How to Get 100% Scores on Core Web Vitals

Join Joe Williams & Aleksandar Savkovic on 29th of March, 2021.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Want to Experience the Cloudways Platform in Its Full Glory?

Take a FREE guided tour of Cloudways and see for yourself how easily you can manage your server & apps on the leading cloud-hosting platform.

Start my tour