Skip to content

Instantly share code, notes, and snippets.

@mirkorap
Last active February 22, 2024 14:51
Show Gist options
  • Select an option

  • Save mirkorap/cd9f2933304eb868e489e7b6b573074c to your computer and use it in GitHub Desktop.

Select an option

Save mirkorap/cd9f2933304eb868e489e7b6b573074c to your computer and use it in GitHub Desktop.
Basic examples how to implement a REST API with Symfony 4 + FOSRestBundle + FOSUserBundle + FOSOauthServerBundle with all oauth2 code flow

How to implement a REST APIs with Symfony 4 + FOSRestBundle + FOSUserBundle + FOSOauthServerBundle using main Oauth2 code flows

Introduction

In this gist I will explain you how to create a basic REST APIs system with Symfony 4 and FOSOauthServerBundle using main Oauth2 code flows. The flows that we implement will be:

  1. Authorization code
  2. Implicit
  3. Password credentials

I will separate the gist into two configuration parts. The first part is the common configuration that is equal for all Oauth2 code flows above. In the second part I will explain, for each code flows above, the basic configuration type that you need. So let's coding!

Install bundles

The first step is to download Symfony and the related bundles.

composer create-project symfony/skeleton oauth2-server
cd oauth2-server
composer require friendsofsymfony/rest-bundle
composer require jms/serializer-bundle
composer require nelmio/api-doc-bundle
composer require friendsofsymfony/user-bundle "~2.0@dev"
composer require friendsofsymfony/oauth-server-bundle

Below I will explain for each bundle what they do and how to configure them.

Configuration

FOSRestBundle

In the config/packages/fos_rest.yaml file insert these configuration options:

fos_rest:
    routing_loader:
        default_format: html
        include_format: true

    format_listener:
        enabled: true
        rules:
             - { path: '^/api', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: false }
             - { path: '^/', priorities: ['html'], fallback_format: html, prefer_extension: false }

    view:
        view_response_listener: true

With the rules above our application will serve for the routes starting with /api only resources formatted in json/xml, instead for all remaining routes it will render simple html pages. The configuration option view_response_listener makes it possible to simply return a View instance from action controllers.

Documentation: https://symfony.com/doc/master/bundles/FOSRestBundle/index.html

JMSSerializerBundle

In the config/packages/jms_serializer.yaml file insert these configuration options:

jms_serializer:
    visitors:
        xml:
            format_output: '%kernel.debug%'

JMSSerializerBundle allows you to serialize your data into a requested output format such as JSON, XML, or YAML.

Documentation: https://jmsyst.com/bundles/JMSSerializerBundle

NelmioApiDocBundle

In the config/packages/nelmio_api_doc.yaml file insert these configuration options:

nelmio_api_doc:
    documentation:
        info:
            title: Oauth Server App
            description: This is my oauth2 server app
            version: 1.0.0

        securityDefinitions:
            Bearer:
                type: apiKey
                description: 'Value: Bearer {access_token}'
                name: Authorization
                in: header
    areas:
        path_patterns:
            - ^/api(?!/doc$)

In the config/routes.yaml file insert this route option:

NelmioApiDocBundle:
    resource: "@NelmioApiDocBundle/Resources/config/routing/swaggerui.xml"
    prefix:   /api/doc

NelmioApiDocBundle is a Symfony's bundle that allow us to generate documentation for our APIs.

Documentation: https://symfony.com/doc/current/bundles/NelmioApiDocBundle/index.html

FOSUserBundle

In the config/packages/fos_user.yaml file insert these configuration options:

fos_user:
    db_driver: orm
    user_class: App\Entity\User
    firewall_name: main

    from_email:
        address: john@example.com
        sender_name: john@example.com

In the config/routes.yaml file insert this route option:

fos_user:
    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

In the config/packages/framework.yaml file insert this line at the end of file:

templating:
    engines: twig

Now let's to create our entity User class:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;

/**
 * @ORM\Table("users")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User extends BaseUser
{

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
     protected $id;

     public function getId(): ?int
     {
        return $this->id;
     }
}
@KosolapovR
Copy link

KosolapovR commented Feb 3, 2020

I do it step by step as you have, but when i try GET localhost:8000/api/users response is:
{"error": "access_denied", "error_description": "OAuth2 authentication required"}
Could you help me?
Note: previous respone was {"access_token":"ZmFkZjQ1NzdjYTY0ZGMwNDYyZDkyNWM1NjU3MmUwZjNiNjIwYTgxYWNmOWZjZDIwZmUyODIwNDFlOWNhZDRmYQ","expires_in":3600,"token_type":"bearer","scope":null,"refresh_token":"Yjk2MmYzMzA1MWU4YTc1YWU2ZTVlMWQyYTI4N2I3NjA5YWE4ZGM4OGMwZDFjYTc1MzJjMDJiZTA2ODE0ZTFiOQ"}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment