This is a migrated thread and some comments may be shown as answers.

Using http interceptor to provide auth token

10 Answers 944 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
asd
Top achievements
Rank 1
asd asked on 10 Nov 2014, 10:14 AM
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.

10 Answers, 1 is accepted

Sort by
0
Alexander Popov
Telerik team
answered on 12 Nov 2014, 08:41 AM
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!
 
0
asd
Top achievements
Rank 1
answered on 12 Nov 2014, 10:49 AM
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.
0
Alexander Popov
Telerik team
answered on 14 Nov 2014, 08:39 AM
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!
 
0
asd
Top achievements
Rank 1
answered on 15 Nov 2014, 08:39 AM
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,
                
            });
0
Alexander Popov
Telerik team
answered on 19 Nov 2014, 07:37 AM
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!
 
0
asd
Top achievements
Rank 1
answered on 19 Nov 2014, 09:16 PM
Thank you for answer. Your solution suits my needs.
0
Fred
Top achievements
Rank 1
answered on 24 Apr 2015, 07:23 PM

Alexander-

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

Thanks,

Fred

0
Alexander Popov
Telerik team
answered on 27 Apr 2015, 06:11 AM
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!
 
0
vladan strigo
Top achievements
Rank 1
answered on 10 Aug 2015, 02:28 PM

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

0
Alexander Popov
Telerik team
answered on 12 Aug 2015, 08:37 AM
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!
 
Tags
Data Source
Asked by
asd
Top achievements
Rank 1
Answers by
Alexander Popov
Telerik team
asd
Top achievements
Rank 1
Fred
Top achievements
Rank 1
vladan strigo
Top achievements
Rank 1
Share this question
or