📜 ⬆️ ⬇️

Simple implementation of Token for mobile application interaction with WebAPI

Recently, I started developing mobile applications using Xamarin.Forms in connection with production needs. Of course, I will not talk about dancing with tambourines in order to write and run the application “Hello, World!” On the emulator, but the main development went smoothly enough.

The benefit and understanding of the task was - namely, the interaction of the mobile application with the database of the internal CRM system in the company, add mobility to employees, but do not forget about security. It was decided to create a WebAPI, because in order to work with already familiar ASMX web services in Xamarin you need to dance with tambourines.

As I said above, including I wanted to make the “link” fairly secure, which means the mobile application must have authorization (to the heap and convenience, with the ability to save authorization and automatic login.
')
I didn’t want to dig deep into WebAPI implementations with authorization at the Token level, but I wanted to do something simpler, especially while I’ve seen googled that people have such a desire in abundance, but all responses that were sent were either standard mechanisms or some packages from NuGet, which I would like to avoid as much as possible.

The base of our own CRM already has all the information for authorization and stupidly did not want to fence something extra.

As a result, after long ordeals, searches, etc. - I think I got a pretty good solution, which I want to share with the community .

So, what we have:

Log in and get token


Again, I will not go into the details of creating WebAPI, I will give an example of the code of the authorization function.

[HttpPost] public LoginResult Logining([FromBody] LoginInfo LogInf) { if (dc.Managers.Count(w => w.EMail.StartsWith(LogInf.PortalUserEMail)) > 0) { if (dc.Managers.Count(w => w.EMail.StartsWith(LogInf.PortalUserEMail) && w.Password == LogInf.PortalUserPassword) > 0) { Managers _man = dc.Managers.First(w => w.EMail.StartsWith(LogInf.PortalUserEMail)); _man.Token = GenerateToken(); dc.SubmitChanges(); return new LoginResult() { Error = null, Token = _man.Token, ValidUser = true, managerInfo = new ManagerInfo() { ManagerId = _man.Id, ManagerName = _man.ManagerName } }; } else { return new LoginResult() { Error = " !", Token = null, ValidUser = false, managerInfo = null }; } } else { return new LoginResult() { Error = "   !", Token = null, ValidUser = false, managerInfo = null }; } } 

I don’t make sense to explain what the function does, too, but as a result, when calling the API, the mobile application receives information that the user is valid and generates the generated Token (I decided not to waste time and put the generation of a 1000-character string out of a large number of characters of the entire English and Russian keyboard, with capital and lowercase letters, numbers, and simple characters.

I prescribe this “pseudo” -Token in
 App.Current.Properties["Token"] = rez.Token; 
applications.

By the way, I think it’s worthwhile to separately mention 3 spent days, version rollbacks, etc. to deal with this very App.Current.Properties .

There was a situation that at some point when restarting the application on the emulator, the contents of App.Current.Properties was missing. Long tormented and trying to understand why everything is lost.

It turns out that while the application is active in App.Current.Properties, any objects can be stored, including objects with data of their own classes, but if the process is “killed”, if there was something different from “simple” objects, the contents of App.Current.Properties it is cleared, but if only simple objects are stored there - string, bool, int, etc. then everything will remain saved!

We continue. All subsequent calls to the API, I provide an additional header:

 var client = new HttpClient(); var address = $"http://.../SomeWebApi/api/Works?ManId=" + ManagerId; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Token", (string)App.Current.Properties["Token"]); HttpResponseMessage response = await client.GetAsync(address); 

What essentially adds to the request header. Now all other WebAPI controllers, before "issuing" anything to the client, verify the presence and correspondence of the pseudo-Token.

For example:

 public IEnumerable<WorkInformation> Get([FromUri] int ManId) { IEnumerable<string> UserToken; if (!Request.Headers.TryGetValues("Token", out UserToken)) { return null; } Managers _CurrManager = dc.Managers.First(w => w.Id == ManId); List<WorkInformation> _list = new List<WorkInformation>(); if (_CurrManager.Token != UserToken.ToArray()[0]) { _list.Add(new WorkInformation() { id = "-1", Client = "   ", DTime = DateTime.Now, Comment = "  ", EventImageName = "" }); return _list; } //      } 

As it seems to me, the resulting implementation of a pseudo-token has a right to exist and can help someone with implementations. I hope the community does not shower with sticks, this is my first post, I hope that there will be not only criticism.

Source: https://habr.com/ru/post/344902/


All Articles