Search code examples
angularjssymfonyfosuserbundlefosoauthserverbundle

why using FOSOAuthServerBundle if FOSUserBundle enough for the security of a RESTful API?


I have a RESTful API (based on FOSRestBundle) consuming an angularJS application that I want to secure. For that I simply used FOSUserBundle which worked as I expected. In fact, the calls to the RESTful API get connected if the I get connected through /login.

So, why FOSOAuthServerBundle should be used if an API will be consumed by an application or a client specially when the API is mine and the application is also mine?

Even, after getting connected through FOSOAuthServerBundle, you will be redirected to a page where you will Allow or Deny the access of the application (which is my application) to my RESTful API. This is not logic at all!!!

Please give me your comment on that.

NB: I added below my security.yml and my angularjs app

security.yml

security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_USER : ROLE_API
        ROLE_ADMIN: ROLE_USER
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:

        dev:
            pattern:      ^/(_(profiler|wdt)|css|images|js)/
            security:     false

        api_doc:
            pattern:      ^/api/doc
            security:     false

        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_token_generator: security.csrf.token_manager
            logout:       true
            anonymous:    true


    access_control:
        - { path: ^/oauth/v2/auth$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/api, roles: [ IS_AUTHENTICATED_FULLY ] }

app.js

angular.module('ads', ['ngRoute', 'restangular'])
        .config(function ($interpolateProvider) {
            $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
        })
        // .config(['RestangularProvider', function(RestangularProvider) {
        //     RestangularProvider.setDefaultHeaders({'Authorization': 'Basic YW1pbmU6c3RpZ21hdGFn'}); //cmVzdGFwaTpzZWNyZXRwdw==
        // }])
        .config(['RestangularProvider', function (RestangularProvider) {
                RestangularProvider.setBaseUrl('/minnapi/web/app_dev.php/api/v1/');
                RestangularProvider.setResponseExtractor(function (response, operation, what, url) {
                    if (operation == 'getList') {
                        return _.toArray(response);
                    } else {
                        return response;
                    }
                });
                RestangularProvider.addRequestInterceptor(function (element, operation, what, url) {
                    var newRequest = {};
                    if (operation == 'post' || operation == 'put') {
                        what = what.split('');
                        what.pop();
                        what = what.join('');
                    }
                    if (operation == 'put') {
                        delete element._links;
                    }

                    newRequest[what] = element;
                    return newRequest;
                });
                RestangularProvider.setRestangularFields({
                    selfLink: '_links.self.href'
                });
                RestangularProvider.setDefaultRequestParams('get', {limit: 100});
            }]);

app-controller.js

angular.module('ads')
        .controller('BrandController', ['$scope', '$routeParams', '$filter', 'Restangular', '$q',
            function ($scope, $routeParams, $filter, Restangular, $q) {
                'use strict';

                $scope.brands = [];
                $scope.newBrand = {name: '', published: true};

                Restangular.all('brands').getList().then(function (brands) {
                    $scope.brands = brands;
                });


                $scope.addBrand = function () {
                    $scope.brands.post($scope.newBrand).then(function (brand) {});
                    $scope.brands.push($scope.newBrand);
                    $scope.newBrand = {name: '', published: true};
                };

            }]);

Solution

  • Simply, if you are not exposing the API to a 3rd party then you don't need the FOSOAuthServerBundle.