1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

License Validation API: Access-Control-Allow-Origin: *

Discussion in 'General XenForo Discussion and Feedback' started by vbresults, Mar 21, 2016.

  1. vbresults

    vbresults Well-Known Member

    It would be useful if license validation could be done on the client side with the visitor's IP, and then that validation result can be double-checked using a server IP without the risk of having the limit exhausted. I guess this goes hand in hand with JSONP support too for older browsers.
  2. digitalpoint

    digitalpoint Well-Known Member

    Are you really needing to make more than 1,000 license validations per day?

    If you are validating the same license over and over (for each visitor viewing the page), you really should consider caching the validation result on your side.
  3. vbresults

    vbresults Well-Known Member

    If someone wants to exhaust the daily limit trying to bypass the validation, let them do it on their own IP I say. If they fail once (on the 2nd server-side validation) then they get locked out, no need for complex caching logic.
  4. digitalpoint

    digitalpoint Well-Known Member

    I guess it just depends on what you are doing with it I suppose. If it's purely just for the user entering it, why have it at all? Just point them to the page and let them do it: https://xenforo.com/api/

    If it's to validate and save on your site if it passed validation, then doing it client side becomes a security risk because your server has to trust the client's browser that what it is telling it is true (would be incredibly easy to falsity validations going into your server then). In that case, it would be like if you asked someone on the street to check a number on a piece of paper you can't see and read it back to you so you can record it as the truth. In *most* cases it will be right, but you will get someone who decides they want to screw with you and give you wrong info. You and your server can't see the ACTUAL info that the client's browser is supposedly repeating back to you.

    So if it's simply a tool for an individual to validate their own license and them spoofing the result serves no purpose, just point them to the real tool. If it's results that anyone else will see, you shouldn't rely on their browser to be "truthful" and you should get the answer yourself.
    ozzy47 likes this.
  5. vbresults

    vbresults Well-Known Member

    It's very simple. The client passes validation on the client side (using JSONP), and sends both their form data and the API response to the server. The server replays the API request. If the API response is different/invalid, which it should never be, they are locked out.

    Why make someone go off-site to validate their license, when they can do it on mine, without using more than 1 of my daily requests ever? Why then put myself in the position where I have to cache API responses? There is no reason to do any of this unless JSONP isn't available.
    Last edited: Mar 24, 2016
  6. Jeremy P

    Jeremy P Well-Known Member

    Maybe I'm confused, but why have the client send the request at all if you're going to "replay" it on your server anyways? I don't see why moving it to be solely server side would consume any more daily requests than the way you describe currently.

    Caching results just seems like a good idea if you are going to need the same result available at a later time.
    Last edited: Mar 24, 2016
    ozzy47 likes this.
  7. digitalpoint

    digitalpoint Well-Known Member

    I guess I'm just not seeing the real world use case where doing client-side validation would ever be better than server-side validation. It's going to be more problematic because you are relying on something out of your control to do it properly and give you a correct/truthful response. You say you are going to somehow validate the response from the client was truthful based on replaying the API request. Not sure I follow you on that, but let's say I do a validation request like so (obviously it wouldn't be done with curl, but just say you wanted a validation response for the token "196094c0c6c4e2b316ae6441799a7ac7":

    curl --data "token=196094c0c6c4e2b316ae6441799a7ac7" https://xenforo.com/api/license-lookup.json
    The client-side tells you the response is this:

    It's super simple to have your browser send your servers that response for a token of "196094c0c6c4e2b316ae6441799a7ac7", even though that response is false and never came from xenforo.com's license validation server.

    So how are you going to validate that the response from the client-side was a truthful response without your server validating it itself?

    I'm really not trying to be argumentative, I'm just trying to understand how you can be relying on something that your server isn't going to be checking itself.
    Daniel Hood and ozzy47 like this.
  8. vbresults

    vbresults Well-Known Member

    To limit the number of server API requests a client can consume to 1. Caching has complexity and drawbacks that could simply be eliminated with a simple client and server side API response integrity check.

    I am validating it with my server, once, after the client side check, and comparing the client and server API responses. If they do not match, which can only happen if data was tampered with, their account is locked out. They get 1 attempt/use of the server's daily limit.

    On the other hand, on the client side, they can make as many attempts as they want. It affects their IP's quota, not mine, and when they finally send the data to my server, that's when I do the one-time check on my (server) side.
    Last edited: Mar 24, 2016
  9. digitalpoint

    digitalpoint Well-Known Member

    Wouldn't it make more sense to do the one time check and save the results for end users?

    There are a couple benefits here:
    • Don't need to write JavaScript code to do client-side validation.
    • Don't need to worry about end users passing back invalid data.
    • Don't need to rely on XF developers to add JSONP support.
    • Don't need to do double validations (once for client-side and again on server-side to make sure it was truthful).
    • If you are only storing license validation codes and not the license status, how are you going to handle it when a license holder changes their license validation code with a single click?
    • It's going to make your site faster for your end users (they don't need to do license validations for each page request).
    • Your site working properly isn't going to rely on xenforo.com being online.
    It kind of reminds me of someone trying to display some sort of feed (like an RSS feed) that goes out and gets the feed live for every page view. In the end you could do it that way, but it's most definitely not the best/right way to do it and not how it's intended to be used.

    I assume you are storing the license validation code, why not store the license status that you got from the server-side check instead? After all, license validation codes can be changed at any time by the license holder.

    At the end of the day, I sounds like you want to make thousands of connections per day to xenforo.com to continuously recheck if a license is still valid when that status is going to change so incredibly rarely (if ever). Which is going to make your site slower for your own users in a best case scenario and error prone in a worst case scenario (if xenforo.com goes down for whatever reason).

    In this case, simpler (server-side checking) is also going to make your site faster. I see no upside whatsoever. Only a whole lot of complexity and slowness.

    On a side note, I *do* use the XF license validation API on my own site like so (required to sell a XF license):

    ozzy47 likes this.
  10. vbresults

    vbresults Well-Known Member

    No, it makes no sense for my use case. All I want to know is if their license is valid and matches the domain, once. I am not storing anything.

    • Don't need to store responses, implement a caching mechanism, or figure out when to invalidate a cache I shouldn't need for my use case.
    • Don't need to worry about users making multiple attempts against my server.
    • Don't need to validate form data on the server side and set up logic to deal with that, only have to sanitize it.
    • I am not storing anything.
    • I am certainly not needing or doing a validation on every page request.
    • If xenforo.com is offline and the data changed before your next cache refresh, you are working with invalid data.
    I am not.

    I do not.

    The above all seemed to come out of the left field, but looking at your implementation I *think* I understand what's happening; you assumed our use cases were identical, and they are not.
  11. vbresults

    vbresults Well-Known Member

    @digitalpoint This could actually be good for your use case too if implemented; instead of checking against cache on every request, implement the double check on the new thread page the way I would, and when people go to view the thread show a "Check License Status" button (triggers a JSONP API request).

    There's then no point in falsifying anything. The API response would truly be "live" and if xf.com is down you can handle that in the JSONP failure callback. You could do away with all the caching stuff and only store the validation token and domain.
    Last edited: Mar 24, 2016
  12. Snog

    Snog Well-Known Member

    I've been following this thread and something doesn't make sense to me.

    The client validates and you revalidate. While YOUR SERVER is only hitting the XF validation server once, your application is hitting it twice. Possibly more, from the client side. Now granted that doesn't affect your quota, but it can affect the performance of the XF validation server.

    If you just validate the user's license once per session from your server (which it seems from your posts you will), you just need to store the license info in the user table put a validation date in the user table too then compare it. It achieves what you're trying to do without any caching involved. You would end up hitting the validation server once per user at the time you would validate the client response anyway.

    This method also allows you to check if more than one person is using the same license info.

    So far as I see it, client side validation really has no viable use.
    Last edited: Mar 24, 2016
  13. vbresults

    vbresults Well-Known Member

    Not once per session. Once per client. One-time only. I am not storing anything. And I do not need to check if more than one person is using the same license info, I have reliable ways to insure against that outside the API. X extra table fields have no viable use, at least not for me.
  14. Snog

    Snog Well-Known Member

    OK, then that works too.

    Validate them once on the server side and if they don't validate after the first try, lock them out.

    Sorry, I just can't seem wrap my head around the need for the client side part of validating a license.
  15. vbresults

    vbresults Well-Known Member

    No, it doesn't. Without a prior client-side validation I can't know for sure if there was a mistake in their input (maybe the last character in the validation token was missing due to a bad copy/paste), or if they tampered with the data.
  16. Snog

    Snog Well-Known Member

    OK, I'll buy the mistake when input as a client side reason to check a license. So what you end up with is something like this...

    1) User enters license info on a form.
    2) When the form is submitted, the client side script checks the license.
    2a) If the client script returns an invalid license, go back to step 1
    2b) If the client script returns a valid response, proceed to step 3​
    3) Valid license input received, begin to process form.
    4) Server validates license input at XF.
    4a) If license input does not match client response, lock out user.
    4b) If license input does match client response, complete processing form.
    I suppose that could be done, but it still seems like extra unneeded steps to me when you could lock out the user after X number of tries from your server. The only way it's really feasible is if you anticipate making more than 1000 validations a day from your server.
    Last edited: Mar 24, 2016
    Daniel Hood likes this.
  17. digitalpoint

    digitalpoint Well-Known Member

    I guess if you explain what your use case is exactly people could better understand what you are trying to do. Maybe there *is* a real-world use case for JSONP and client-side validation, but I can't think of what that might be myself. I would think if you present what you use case is exactly, you would have a better chance of XenForo developers making the needed changes for you.
    Snog likes this.
  18. vbresults

    vbresults Well-Known Member

    @Snog There is no going back, I just stop the form from submitting. @digitalpoint I am using the API to validate forums after they purchase a premium product.
    1. Client enters validation token (we already have domain recorded on our side) and it's checked with a client-side API-request
    2. Client submits. If valid, continue submitting the form appended with API response information. If not (e.g. typo), stop form submission to server, show error
    3. Server replays the API request and checks against the data. If valid, continue, if not, lock out the client.
    It shouldn't have to be any more complicated than this.
  19. digitalpoint

    digitalpoint Well-Known Member

    Agreed, but you could make it simpler. Wouldn't it be simpler to combine step 1 and 2? Client enters validation token as part of their submission? Check it on the server-side since you want to do that anyway to verify the client response is truthful. If it's invalid, lock out the client and form doesn't submit. You don't need to cache anything or store anything since you aren't try to redisplay the results to anyone. You don't need to write custom JavaScript code to make a JSONP call, get the results and pass it back to your server.

    I guess I don't understand why you want to have that extra complexity when you aren't going to trust the response and redo it yourself on the server-side anyway? Why not just start with the server-side call and keep it simple?
    Snog and ozzy47 like this.
  20. Jeremy P

    Jeremy P Well-Known Member

    If I'm not mistaken, he's using the client-side request to essentially perform validation so that he doesn't waste a server API call for an invalid request. Once the client performs a (presumably) valid request, he tests it on the server side.

    Maybe it would reduce the complexity involved if invalid requests didn't count towards the limit (or had a separate limit), instead of adding JSONP support and performing client-side validation at all.
    Daniel Hood and vbresults like this.

Share This Page