B
B
babaevmm2016-11-09 13:47:21
ASP.NET
babaevmm, 2016-11-09 13:47:21

What is the correct sequence to call Web Api methods?

Hello!
I continue to study MVC 5 and API. I have a question that I can't find a definitive answer to. With a combination in one project MVC and API helped me here. I created a project according to the SPA template, described the custom authorization (I described the model myself, the PostgreSql base through Dapper). I got to the design of the API part and the question arose: what should be the procedure for calling the API through external clients and if the call goes through my own site? Sometimes I thought about creating an MVC layer -> WEB API -> DATA, but I read somewhere that this is not the most successful architecture - is it so in your opinion?
Returning to the main question, while the following is emerging in my head (which I have already tried in practice): to call any method in the API, you must first call the method for authentication (Login), and then use the received token to call the desired method (passing the token in the header ), described here ( metanit.com/sharp/aspnet_webapi/5.2.php). And as I understand it, EVERY time. This confuses. Is there any other method? I read about REST, so here it is, as it were, "does not support states", i.e. in theory, we should get everything with one request. Maybe I'm wrong?
The second option: call the API through your site (not always, but only allowed in the testing or administration window) - if not authorized, then everything is fine - it should not allow me. But now, in order to store the token, I have to implement logic so that the token is stored during authentication (sessionStorage.setItem(tokenKey, data.access_token);), which again is confusing (needs to be taken care of).
Please explain and do not kick much.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Nemiro, 2016-11-09
@babaevmm

The access token is entered once. On the client side, it is stored in sessiongStorage or in cookies . Used on every API request . As a rule, it is better to pass the access token through headers. When using HTTPS , the headers will be encrypted.
To improve security, the server can issue an access token tied to a specific IP (you can make it even more complicated, for example, check the browser, system type, etc.). If the client's address does not match the address in the database, then revoke the access token and offer the client a new access token. The access token can
expireshould be limited. The validity period depends on the conditions of use and the required degree of security. For example, if the token is bound to IP , then the expiration time may well be long.
On the server side, you can make a separate filter to check access, something like shown in the code below:

class ApiAccess : AuthorizeAttribute
{

  public override void OnAuthorization(HttpActionContext actionContext)
  {
    if (actionContext == null)
    {
      throw new ArgumentNullException("actionContext");
    }

    if (!this.IsAuthorized(actionContext))
    {
      return;
    }
  }

  protected override bool IsAuthorized(HttpActionContext actionContext)
  {
    bool isAuthroized = base.IsAuthorized(actionContext);

    // логика проверки доступа

    IEnumerable<string> authItems;
    if (actionContext.Request.Headers.TryGetValues("Authorization", out authItems))
    {
      var auth = authItems.First().Split(' ');
      var token = service.GetToken(auth.Last());
      // ...
    }

    return isAuthroized;
  }
}

The filter is added to WebAPI controllers where access checking is needed:
[ApiAccess]
public class FileServerController : ApiController
{

   // ...

}

From the client side, it's easier to make a helper method that will send requests to the API using an access token, and also check if a new access token is required (if the server returns an error). Approximately as shown in the following code:
let url = '/методAPI';
let data = {}; // параметры запроса
let headers = {
  'Authorization': 'ANYNAMEHERE ' + sessionStorage.getItem('token')
};

$.ajax({
  cache: false,
  processData: false,
  type: 'POST',
  url: url,
  contentType: 'application/json',
  dataType: 'json',
  data: JSON.stringify(data),
  headers: headers,
  success: (result) => {
    // успех
  },
  error: (x, textStatus, errorThrown) => {
     // ошибка

     // на сервер можно сделать исключение для плохих маркеров доступа
     // и проверить, если responseText содержит данный тип исключения,
     // то требовать у пользователя повторную авторизацию
    if (x.responseText) {
       let exception = JSON.parse(x.responseText);
       // AccessDeniedException - тип исключения в WebAPI, 
       // (скорее всего полное имя типа придется указывать)
       if (exception.ExceptionType == 'AccessDeniedException') { 
          // ...
       }
    }
  }
});

As for obtaining an access token by the user, this can be done in any convenient way. For example, show a modal window for entering a username and password, or redirect to a separate page.
If the API is used through a separate ( API -independent ) site that authorizes users, then the user can not be involved in the procedure for obtaining a new access token, the site can do it itself and pass the new token to its user.
If the API is used in the browser as is, then the access token can be passed in the request parameters. However, this is not safe, because the data will be in the open.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question