Ankit Vijay
Ankit Vijay

Reputation: 4108

Using HttpCookie for timeout/ url expiration

I'm working a web application, which is MVC 5 + Angular JS hybrid. There is no authentication in the web app and an anonymous user can come and ask for price for certain services. To get the price the user needs to answer some questions spread across few pages. Here is the flow of app.

  1. User clicks button to get price

  2. A unique URI the request is generated and user is redirect to the questions page

  3. User answers questions and user submits the answers. The questions are spread across multiple pages navigated through angular routing. The answers are saved back to server on page navigation.

  4. Once, the user submits the answers, the system (server) generate the price and display it to user.

Currently, if the user has bookmarked the URI, he can come back after days and continue from where he left. I want to prevent this behaviour.

What are the different options do I have in MVC? I can think of following:

  1. Using HttpCookie with expiration time

  2. Save the last access time in DB and validate if the user has come within a stipulated time frame?

I would like to avoid HttpSession. I'm inclined towards using HttpCookie since it looks to be the simplest option.

  1. If we go with HttpCookie option, are there any side effect that I need to keep in mind?

  2. Are there any other alternative within MVC I can look for?

Upvotes: 6

Views: 720

Answers (3)

Vlad
Vlad

Reputation: 51

I'd rather generate a token for a unique user session and store it on the server along with CreatedDate. So URL will have a token query string parameter that will be validated against the date.

  • It's more secure than relying on cookies
  • Allows for adding analytics to your site, where you start storing q/a combinations along with generated prices for a given user session. Start collecting data early. :)

Upvotes: 3

Alex Lyalka
Alex Lyalka

Reputation: 1651

If You want to expire some link without storage involved and your service need to be scaled I think You just need to add expiration date in your link and sign it.

I believe you can create your URL in a way like this

Pseudocode:

var info = [Payload any info you need to store(questionnaire id or so)] + [expirationDate]
var sign = HMAC256(info + [SERVER_SECRET])
var clientLinkParameter = info + sign
var clientLink = [baseURL] + [delimiter] + Base64(clientLinkParameter)

*HMAC256 - it's just example you can create signature using any algorithm you want

Now you can just check your link for expiration by parsing serialized data in the part before delimiter. You can also check that date was not modified by checking:

HMAC256([partBeforeDelimiter] + [SERVER_SECRET]) and [partAfterDelimiter] for equality. If they match this is the link your server sent (as only your servers know what the [SERVER_SECRET] is) otherwise it was modified by the client.

Now you can store any non secret data in user link allow user to share this link and other great things that you can do with a link without worrying that someone modify our link. Client can deserialize first part as well if its widely known serialization algorithm like JSON.

I think this flow will bring better user experience in case of suddenly closed browser (that will clean cookies in your case) and also sharing link with someone (if you need)

Hope this will help.

Upvotes: 4

Ankit Vijay
Ankit Vijay

Reputation: 4108

I finally, went with session-cookie. I hashed the unique id and saved it in the cookie with salt. I feel this is a reasonable approach for following reasons:

  1. The anonymous user session is going to be short lived. Once, he closes the browser the cookie gets removed.

  2. If the user bookmarks the URI, I look for session-cookie in the Http Request. If the session cookie is not found, I redirect the user to the challenge page.

I have gone for MD5 algorithm for hashing. I understand it is collision prone, but is faster than SHA. Since I do not store sensitive information like password in the cookie, I guess it should be fine.

Upvotes: 3

Related Questions