Maintain session in subsequent request in WEB API for OTP verification - c#

I am working on one MVC application, where there is separate WEB API project also.
Now I want to implement update email functionality based on OTP verification from mobile via WEB API.
Web API is stateless but still, I want to implement SESSION in my code so that I can access OTP value in subsequence request and validate it. Currently, I am able to store OTP in session in the first request but in next request Session is null and I can not access stored OTP value.
I do not want database trip to store and retrieve the OTP.
public HttpResponseMessage SendOtpOnMobile([FromBody]OtpOnMobileAPIRequest objOtpOnMobileAPIRequest)
{
otpValue = CommonUtility.GenerateRandomOTP(4);
HttpContext.Current.Session["otpGeneratedValue"] = otpValue;
//Send OTP logic and response code
....
}
public HttpResponseMessage ValidateOtpFromMobile([FromBody]ValidateOtpFromMobileAPIRequest objValidateOtpFromMobileAPIRequest)
{
var otpGeneratedValue = HttpContext.Current.Session["otpGeneratedValue"];
if(objValidateOtpFromMobileAPIRequest.OTP == otpGeneratedValue)
{
//success
}
....
}
I have tried following URLs.
ASP.NET Web API session or something?
Accessing Session Using ASP.NET Web API

What you want to do and what is achievable are two different things.
Each call to the API will be discrete and won't keep track of previous requests. However, since you have an MVC app as well, I suggest you maintain the session there and simply pass whatever you want to the API as a parameter, for example.
So, return the OTP code you generated to your MVC app, if you can, and store it in session there then on subsequent API requests, pass it through from your web app.
It would help if you described the flow of your application, as suggestions will be based on that.
If you have multiple clients using your API, then each one of them will have to either maintain data required to function properly, or you will need to do that extra database trip. It's up to you which solution works better for your specific scenario.

Thats great you know "API's are stateless". I am completely agree with the words of Andrei
What you want to do and what is achievable are two different things.
If you dont want to store the OTP in your database then why dont you pass OTP in HttpRequestHeader.
Pass the OTP in your header (Preferred encrypted OTP and then decrypt it in your WEB API.
Suggesting this way as per your needs

Related

One Asp.Net Core Api Service for Multi-site

I want to create only one Asp.Net Core API Service for multiple website. they are almost same but have different content.
i want to know which website call API to return that website's contents.
for example :
Web Site One(angular client) : http://Game.medis.land
Web Site Two(angular client) : http://Tech.medis.land
API(/api/getservices) => return All Services (depend on which site call the API, method return different values)
if Site-One call =>{"previews","reviews"}
if Site-Two call =>{"software","hardware"}
how should i manage this? can i get URL from Header of request? or something else?
There are many ways that you can handle it:
1- ClientType: every clients should introduce theirself for example Client B set a header key in all requests (ex: ClientType:client-b) and you can determine your clients.
2- Origin: you can read the Origin from request headers and determine clients by their domains but I think it's not good idea because may be domains changed any times.
3-Api key: you can generate a unique key for every clients( Guid is a good choice) and clients should set their api key in all request header(ex api-key: XXXXXXXX) and in server side determine the clients by key.
Finally I suggest you that handle clients in a middleware and pass it with http features to your controllers.

How to retrieve a payment method on the client side?

We are running an App with a Angular/Typescript frontend and a .NET backend, using Stripe Elements and Stripe.NET respectively.
We are currently using the "Sources" API.
The frontend can create sources, the backend saves them to our specific users. When you open the frontend again, the backend sends a list of source ids. The frontend then collects the data it needs to display those sources directly from Stripe so the user can pick one of his saved sources to pay and does not have to enter all the data again.
Enter the Payment Method / Payment Intend API.
Due to EU regulations Stripe has a new API that requires us to create cards no longer as "source" but as a "PaymentMethod". So I implemented that in the backend, opened the frontend in my IDE, updated the #types/stripe-v3 package and found the new payment intent API.
The only thing missing: I cannot figure out how the frontend is to access the payment method data, once created. I can create it. Send it to the backend. The backend can retrieve it. Send back the ID to the frontend... and now what? How to display the payment methods available?
I had expected a stripe.retrievePaymentMethod() as there is a stripe.retrieveSource(). But no such luck.
The only option I currently see to present the user with a list of existing payment methods is getting this info on the backend and piping it all, class by class, property by property to the client. Basically copying every single data class stripe has into our own backend REST definition. That cannot be right.
What am I missing? Why is there no stripe.retrievePaymentMethod() on the frontend? Did I not understand some fundamental facts about what those APIs should do?
After contacting Stripe directly, it was confirmed that that's just the way it is:
I think it's just an oversight that we didn't add one.
There are similar functions in the mobile SDK so I don't see why we shouldn't have it
There are no immediate plans to add the functionality back in in the very near future,
so as a workaround, I will tunnel all the data through our backend(s).
If I understand as well, I think your problem is following and the sequence of that. I hope this helps you.
I have implemented a payment gateway like ccAvenue with DotNet and angular, in my case, I send the data to the server, and from the server, I tried to redirect to the payment gateway, but APIs return some result, and the result can not be redirected.
So I created a web-form with implementation, I redirected my app to web-forms page and from there I called the ccAvenue page, and in the response URL, I send the response page of webforms only and after saving the response I redirected to my angular app.
Here is workaround if you want to process 3Dsecure cards and still support other methods like SEPA.
You could attach both, confirmed PaymentIntent (payment method) or Source to the Customer object.
On your frontend you could implement both (StripeElements with client secret for 3Dsecure cards) and IBAN element for SEPA.
I could provide my code example how I save payment intent to the customer. It's in PHP, but for other languages logic should be the same.
Assuming that our client already confirmed PaymentIntent and we have it's id:
$intent = \Stripe\PaymentIntent::retrieve($stripe_intent_id);
$payment_method = \Stripe\PaymentMethod::retrieve($intent->payment_method);
$stripe_customer = Stripe\Customer::create([
'payment_method' => $intent->payment_method,
]);
In case you've already created Customer object before you could use attach method:
$payment_method->attach(['customer' => 'cus_FTkGe4lv5LfyI0']);
Then you'll be able to charge using Customer object PaymentMethod or Source;
I didn't try to attach both methods to the same customer object (we only allow customer to have one payment option at the same time), but it should work. Let me know if it works for you.

How to save tokens between apis without statement?

We're thinking about an architecture for our next app and we're having problems with pass the tokens between apis. We'll have:
Front -->(call to) own login api (if all is ok we create an own token, named ownToken) -->(call to) third party api --> returns a JWT token (named 1token) -->
After everything is ok :
Front --> User do some tasks-->(With ownToken Call to) own business api (If ownToken is ok, do some stuffs)--> (with the 1token Call to) third party api (return some stuffs) --> Show information to the user.
We want to avoid calling the third party api every time that we want information from that api, but also we don't want to show that JWT to the user (I mean localstorage,sessionstorage...).
For more information, we'll use c# language and sql server as database.
Our question:
How do you mantain 1token between APIs?
you have two different things which need to be managed:
JWT-secured calls between your front-end and your back-end
JWT-secured calls between your back-end and a 3rd party.
What I would do is simply generate a 'sessionId' in the back-end which is part of the token you send to your front end. this could be an int or guid or whatever.
I would then associate this 'sessionId' with the token retrieved from the 3rd party and store that somehow - some form of database or file storage (DB would be the obvious thing to use).
That way whenever a request comes in from your front end in your back-end code you should:
Extract sessionId from the token they provide
lookup the entry for this Id in your database to get the token associated with it
use this token to make whatever calls are required and respond
You'd have to make sure to update this association whenever you need to get new tokens, but that shouldn't be too hard.
You could also use this to make the nature of the thing a bit more async - you could return immediately to your front end with a response suggesting it's 'Working On It' then the front end could call a separate endpoint later to get the results... That way if the 3rd party link takes a while then the original request isn't left waiting too long for a response...

How to implement a callback URL to receive a json data in c#

For some days now i have been struggling on a project where i need to provide a URL to enable me to receive a JSON response(precisely this my first time of calling a web API)
This is the scenario:
- First the company has a web service that i need to consume and send a bill prompt to our client and so far it has been successful
- Second , they ask me to implement a callback and give them the URL where they will call me to send the status of the bill whether our client has confirm the bill prompt or not(this is where i am stacked)
When i get the JSON data i can easily use it to do what i want but my problem is how to implement the web page that the company will call to send the status.
Please a sample code will help me a lot.Thanks
What you are trying to achieve is called WebAPI. You expose HTTP endpoints using Controllers to the Internet and consumers of your API may utilize them to POST the status back.
You are describing creating an API. Basically, you create an endpoint url using a controller in C#. It's within this controller that you receive data from "the company" and process it, and do whatever you need to do after that. If you use the standard MVC framework build into C#, it's fairly straight-forward. Here is an example of a callback url we are using in a three-legged OAuth procedure. The last step involves a third party sending a request to our callback url and posting some data. We are using a model as a parameter. But you can use simple structures (int, string, etc) as well. As log as the names of your params match the names that the third party sends in their query string or POST, the MVC framework will handle the variable assignment automatically. The serialization/deserialization is built in to the framework.
Here is a small example of how we have implemented a callback url in one of our apps:
public class MyAuthenticatedController : Controller
{
public ActionResult Index([FromUri]MyAuthenticatedModel model)
{
logTheResponse(model);
if (model == null)
{
throw new HttpException(401, "Auth Failed");
}
}
}
The third party would hit the url:
http://app.mydomain.com/myauthenticated
Using the GET method.
If you don't want to build an ASP.NET Web API Project, you can do this easily with an Azure Function.
See: https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-generic-webhook-triggered-function

C# Web API - Security for some of the GET requests

On an existing host I've added Web API Models & Controllers. I've added the following four:
Products
Orders
Categories
Users
When someone accesses the localhost:port\api\products, it returns all the products in JSON format.
The Create, Update and Delete statements are completely disabled, so we are only able to use GET-requests on the API (so either \api\products for a list of all products or api\products\# for a single products with id #).
Because the other CRUD's aren't used, there isn't a lot of security that should be added to the Web API, except for one thing: The Users
These will also return emails and such, which would be better to keep private and unreadable without the proper authorization (without entire log-in pages, but a way to authenticate yourself when accessing the Web API in for example Android HttpGetRequests).
So, the question: How should I add authorization for only the UsersController accessed by the Web API.
And, how can I encrypt the JSON in C# and decrypt it in Android again. If this second part is too big to answer I'll make a new question later on, my main focus is the low-end [<- without log-in pages, so built in into the GET-request] authorization of the Web API's GET-request for Users.
Edit 1: I did found this link where a new project is made with Authorization Changed to Individual Users. I also see that the user is registered and then logged in with POST and GET requests.
The following questions came into mind when reading through this link:
How to change the Web API's Authorization to Individual Users on an existing project?
Our authorization is done through OAuth (mainly Google-account) with our work e-mail address. I guess it's not possible / easy to authorize in the same way as in the link with a Google-account on Web API GET-requests.
Edit 2: After using the first link provided by Vladimir Gondarev I've added the [Authorize] to both the Get methods in the UsersController. In my project everything else was already used before, like a class that uses the AuthorizeAttribute, so just adding the [Authorize] was already enough for the first step. Now in the browser I get an unauthorized (JSON) back when I'm not logged in, which is good.
The next step would be to add the OAuth-authorization to the Android app, but that is an entire new problem / question that I will look into first before asking a new stackoverflow-question.
The simplest solution would be "Basic Authentification". In order to to implement it you have to derive from AuthorizeAttribute and then apply it to a method or a controller.
Here you find further info:
What is basic Authentification:
http://www.asp.net/web-api/overview/security/basic-authentication
Implementation:
ASP.net Web API RESTful web service + Basic authentication
You don't have to encrypt anything as long as you use HTTPS transport.

Categories

Resources