Using http interceptor to provide auth token

11 posts, 0 answers
  1. asd
    asd avatar
    10 posts
    Member since:
    Oct 2014

    Posted 10 Nov 2014 Link to this post

    Hello,
    I have angular js application using kendo. In angular I defined http interceptor which adds auth token to every request:
    public request = (config) =>
    {
        config.headers = config.headers || {};
     
        var authData = this.localStorage.AuthorizationData;
        if (authData)
        {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }
     
        return config;

    }

    Iam also using webapi so to populate grid I have to use beforeSend in DataSource and set there token:
    $scope.people = new kendo.data.DataSource({
        transport: {
            read: {
                url: Config.ApiUrl + 'doctors',
                dataType: 'json',
                beforeSend: (xhr) =>
                {
                    var auth = "Bearer " + token;
                    xhr.setRequestHeader("Authorization", auth);
                }
            },
        },
        pageSize: 5,
                    
    });

    Is it possible to make datasource use my httpinterceptor as function that provides the token to the request? I just want to have token setup in one place.
  2. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 12 Nov 2014 Link to this post

    Hello,

    I am not sure I understand what exactly you are trying to achieve, however the DataSource's transport allows you to use functions for the CRUD operations (see documentation). This gives the application developer a lot of flexibility and is probably something that would be useful in the case you are dealing with.

    Regards,
    Alexander Popov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. asd
    asd avatar
    10 posts
    Member since:
    Oct 2014

    Posted 12 Nov 2014 in reply to Alexander Popov Link to this post

    The problem is that everytime I want to make call to webapi I have to set auth bearer token. My interceptor handles this by himself. Whenever I use angular resource or $http call to webapi before sending the call interceptor adds the token. Using kendo I have to specify the token in datasource as you see in example. The interceptor doesnt work with kendo datasource. The problem now is that I have to add bearer token in 2 places: in interceptor and in kendo datasource. I would like to have it only in interceptor. Is it possible to integrate it somehow?

    Crud solution wont work for me as my model in add/edit differs slightly from the model for grid row.
  5. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 14 Nov 2014 Link to this post

    Hi again,

    Using a function in the DataSource's transport should allow you to use the Angular's $http method, so the request would be handled by the interceptor.

    Regards,
    Alexander Popov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. asd
    asd avatar
    10 posts
    Member since:
    Oct 2014

    Posted 15 Nov 2014 in reply to Alexander Popov Link to this post

    Could you provide working example?
    My DataSource looks like this and it doesnt work:
                var dataSource = new kendo.data.DataSource(
                {
                    transport:
                    {
                        read:
                        {
                            url: Config.ApiUrl + 'doctors',
                            dataType: 'json'
                            /*beforeSend: (xhr) =>
                            {
                                var auth = "Bearer " + token;
                                xhr.setRequestHeader("Authorization", auth);
                            }*/
                        },
                    },
                    schema:
                    {
                        model: { id: "Id" }
                    },
                    pageSize: 5,
                    
                });
  7. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 19 Nov 2014 Link to this post

    Hello,

    Here is a proof of concept example illustrating how the Angular's $http method could be called from withing the DataSource's transport.

    Regards,
    Alexander Popov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  8. asd
    asd avatar
    10 posts
    Member since:
    Oct 2014

    Posted 19 Nov 2014 in reply to Alexander Popov Link to this post

    Thank you for answer. Your solution suits my needs.
  9. Fred
    Fred avatar
    1 posts
    Member since:
    Nov 2013

    Posted 24 Apr 2015 in reply to Alexander Popov Link to this post

    Alexander-

     I need to do the same but the dojo link isn't working. Can you re-post?

    Thanks,

    Fred

  10. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 27 Apr 2015 Link to this post

    Hello Fred,

    Here is the entire code: 
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Untitled</title>
     
     
        <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    </head>
      <body ng-app="app">
        <div ng-controller="MyCtrl">
          <kendo-grid options="GridOptions" k-data-source="GridDataSource"></kendo-grid>
        </div>
        <script>
          'use strict';
          var app = angular.module("app", [ "kendo.directives" ]);
           
           
          function MyCtrl($scope, $http) {
            $scope.GridOptions = {
              sortable: true,
              pageable: true,
              columns: [{
                field: "FirstName",
                title: "First Name",
                width: "120px"
              },{
                field: "LastName",
                title: "Last Name",
                width: "120px"
              },{
                field: "Country",
                width: "120px"
              },{
                field: "City",
                width: "120px"
              },{
                field: "Title"
              }]
            };
     
            $scope.GridDataSource = new kendo.data.DataSource({
              type: "odata",
              transport: {
                read: function(o){
                    $http.get("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Employees").success(function(response){
                    console.log(response)
                    o.success(response)
                  })
                }
              },
              schema: {
                data: "d"
              },
              pageSize: 5,
              serverPaging: true,
              serverSorting: true
            });
          }
          // register the interceptor during module config
          app.config( function( $httpProvider ) {
            $httpProvider.responseInterceptors.push( interceptor );
          } );
          var interceptor = function( $q ) {
            return function( promise ) {
              var resolve = function( value ) {
                console.log( "resolve: ", value );
              };
     
              var reject = function( reason ) {
                console.log( "rejected because: ", reason );
              };
     
              // attach our actions
              promise.then( resolve, reject );
     
              // return the original promise
              return promise;
            }
          };
        </script>
      </body>
    </html>


    Regards,
    Alexander Popov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  11. vladan strigo
    vladan strigo avatar
    18 posts
    Member since:
    Apr 2005

    Posted 10 Aug 2015 Link to this post

    Hi Alexander

    This works good except the pagination and other filters which goes in query string of the request. In other words, I'm not able to use server filtering, paging and sorting options. As you can see, you set the "pageSize" option to 5, but there are 9 results shown in the grid.

    Is there any way to make it work?

    Thanks

    Vladan

  12. Alexander Popov
    Admin
    Alexander Popov avatar
    1416 posts

    Posted 12 Aug 2015 Link to this post

    Hello Vladan,

    This is expected, because the paging and sorting options are not passed to the service:  
    read: function(o){
        $http.get("http://demos.telerik.com/kendo-ui/service/Northwind.svc/Employees").success(function(response){
        console.log(response)
        o.success(response)
      })
    In this case, the "o" argument contains the take, skip, page, pageSize and sort options. If the service supports server-side operations, passing those options to it should yield the expected results.

    Regards,
    Alexander Popov
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready