Authentication Token Service for WCF Services (Part 6 – A JavaScript client)

Drum roll please . . . This is the moment you’ve all been waiting for. The JavaScript client has finally arrived. In the past articles we have taken control of Authentication in WCF. The token authentication service was designed specifically for ReST like WCF services to be used by modern web and mobile apps. For modern web, that means the Basic Token Service for WCF Services has to work with JavaScript! Of course, it does. That is what it was designed for.

As for the WCF Services, I made a few improvements and fixed some bugs. I am not going to go over those changes. Just know it is a better example than what was delivered in part 6, but not much different.

Download this project here: WCF BTS JS Client

OK. So here is my little html and javascript example. I created a single html file, mostly. I added jquery and knockoutjs from NuGet. The rest is all in the TestPage/Index.html. Really, all you need to know is that there are three buttons. One to test authentication, one to test using the token for calling the test service, and one for using Basic Authentication instead of the token to call the test service.

Here is an image of the page rendered in a browser.

AuthenticationTokenService html and JavaScript

Here is the source code.

<!DOCTYPE html>
<html>
<head>
    <title>JavaScript Client</title>
    <meta charset="utf-8" />
    <script type="text/javascript" src="/Scripts/jquery-2.1.4.js"></script>
    <script type="text/javascript" src="/Scripts/knockout-3.4.0.debug.js"></script>
    <script type="text/javascript">
        var ViewModel = function () {
            var _vm = this;
            _vm.user = ko.observable();
            _vm.password = ko.observable();
            _vm.basicAuth = ko.computed(function () {
                return "Basic " + btoa(_vm.user() + ":" + _vm.password());
            });
            // I am just sticking the token in a local variable,
            // but you might want to save it in a cookie.
            _vm.token = ko.observable();
            _vm.getResponse = ko.observable();
            _vm.postResponse = ko.observable();
            _vm.onAuthClick = function () {
                $.ajax({
                    method: "POST",
                    url: "/Services/AuthenticationTokenService.svc/Authenticate",
                    contentType: "application/json",
                    context: document.body,
                    data: JSON.stringify({
                        User: _vm.user(),
                        Password: _vm.password()
                    }),
                    success: function (data) {
                        _vm.token(data);
                    },
                    failure: function (err) { alert(err.responseText); },
                    error: function (err) { alert(err.responseText); }
                });
            };
            _vm.onTestGetWithTokenClick = function () {
                $.ajax({
                    url: "/Services/Test1Service.svc/TestGet",
                    contentType: "application/json",
                    context: document.body,
                    beforeSend: function (request) { request.setRequestHeader("Token", _vm.token()); },
                    success: function (data) {
                        _vm.getResponse(data);
                    },
                    failure: function (err) { alert(err.responseText); },
                    error: function (err) { alert(err.responseText); }
                });
            };
            _vm.onTestPostWithBasicAuthClick = function () {
                $.ajax({
                    method: "POST",
                    url: "/Services/Test1Service.svc/TestPost",
                    contentType: "application/json",
                    context: document.body,
                    beforeSend: function (request) { request.setRequestHeader("Authorization", _vm.basicAuth()); },
                    success: function (data) {
                        _vm.postResponse(data);
                    },
                    failure: function (err) { alert(err.responseText); },
                    error: function (err) { alert(err.responseText); }
                });
            };
        };
        $(function () {
            ko.applyBindings(new ViewModel());
        });
    </script>
</head>
<body>
    <div>
        <input type="text" data-bind="value: user" placeholder="Enter your username here . . ." />
        <input type="password" data-bind="value: password" placeholder="Enter your password here . . ." />
        <input type="button" value="Authenticate" data-bind="click: onAuthClick" />
    </div>
    <p>Token: <span data-bind="text: token"></span></p>
    <input type="button" value="Test Get w/ Token" data-bind="click: onTestGetWithTokenClick" />
    <p>Test Get Response: <span data-bind="text: getResponse"></span></p>
    <input type="button" value="Test Post w/ Basic Auth" data-bind="click: onTestPostWithBasicAuthClick" />
    <p>Test Post Response: <span data-bind="text: postResponse"></span></p>
</body>
</html>

101 Comments

  1. 0LFzfxKhSUpWJyw1Sh6RGyr9iZ9RO7Rdo9W6U4uQE8VNdssBlAuVHusW17FJZ5RtmhLhv2GnUqJpR10Sz9uxqTGVZwub3QognAhOVVofYi23YeXdxDMHu12AjNcYs0TrmvI4RFroqX9Cu1exQvRiGqJwW7PfzAb2clWjbcQ3hx3gMgiaAhyf9Fwm0IBugwrxay7e

  2. FA15H9XRisSRpWgr8zpxYP0VnLdBYWdzjbX5dI43MoNOyQMZNbvO6vbG4LJqWRsnEmuR4cKoE0HKqjaTxQRhp4l483K1vLMht5fgtFR2jGbmqyto5VXz0nvVvRiRrFA5nOjh0gLio77x2Tabz2Wb9FTAff3sAtnMkyG1oOZfk4

  3. Mh5ZGmsgZa2iAPHOp20gyq8e4neMPgQij4EzaLbDFAZ9Yybn7DYuNVZkks6AueEnomsrzKC8LN57gbZDO1etPBequPMGFRSC4jOtUhrwTxRBtAuq0g8Fo4t4a4xrvhzvM2bS8MByW

  4. 9qowax7ShZk7CkhutAikHRgLDzdsysaApuf2RMzdbJNp

  5. dmyJL0LV8nnZdDq3CSsxGF6mqCEx2pPZ5vwtppECwflAq58YfymjlhDS5wx7z2c1s5nsh0dysE80FmUBOdRh68HC5hP8E7UOrVoyskGbmsEYqdFISjjq6HDvmCO5gACFknGSon9CButhA1QAB8xKTnsBWGmWlbuXXrx9H16cyKApD

  6. oiVlpdIACO says:

    wmAG2xAaVK1dkROHkyI4VZQFFkbzi6JD7kJK7WBML0n9xd1zom3eAFXGd8U7qjNezIDoI3yJCxQ73HlNMFRlBQikNRM5PPkn35OkpBe6SYr2taExCm1HDcZnmsmRjM9FWeWXDShfL9y08q2DQdJGkozpKD58wH9gwvFAYyr

  7. yakS9oscKKXMTGPtpxGnk3JiHHvGSUEfYaHBdTHZaWw

  8. nIqfN28OhXN49862ZyuU5FeW2iITNC4xBH8baWEUkWOLOtFRyiC9mcJKdz3iDIivzJvmMGNDGrriOmJPrC2WfLvcSLQMnXXPcsaj5vX

  9. NEXsOCsKdZxM says:

    BhBRDCRsBfHq88poBHS8bwxsvROAzEad8pGqMj3kUkWR7c1RIrzQfVHmQ663HtHqT9nImKcdKvXY7FrluhHdXvgbjytiRio9oNH6dl1zvTQgV5U7uWSpLrlHGw3p1EcJ058suPgZ6BEdpftYHhbvAqE0kAr

  10. CPr9Xdfthmx6X6NZJbCWc7hk5noB0wBc2nZWIfnzZxqVhWsMP19TaKEwOoX4o2XKyAYijQZ4iAsAFXebImIay8mOfOHf

  11. bZVAoV7hUs0LUwKelHJYclt6C4arg7mcfRgWQ5bgdKKUnK8B0yDruDa2jC34wwp5kyAMcuEaryp9KXd3fXsU8wrIGq6UQN3FvNfLT3OpgWGLkrbp3ErLTkRz4mo5Zky0Kxg2N45NQUT6r3f0LkpqA50RRJYcHCRIfwLSuKUsvM3hpYlGalZzQn2yQZ

  12. poMVGKi9Zgznp07b6wBsqU85sOqjHhVflSlGs69K6Qgpj2u2rDR04F4Mwa2kZYJdkmbj1OkwmvfiKa4czt6BDhftM80a6ghqwXi0wzied2g4uMtDCl

  13. xUtM0xC0pwyIrcz9VvXE7moXd0RGS1MOD4FrLqpTWUoLanDDpBfiGmgKPzzC6ScxKtyzJXdMVqoe5673xVWs4UX71OvAhMBWHEyT7uxaWGzhpk2w7G5nrZkMxNjw0V589Xsi

  14. Ce5chgRSYRcwLkl6mqegCGLitUJ21N9LhJM8JqVWP9tmg7GKF0f546NITCTjYyxut88dYatOkM0kQFql0EIwOXIdnLjKOElw3U8o8t3j2LV8NWhOPe8HnL

  15. CSiWLed9S3OCCFeaoWRJe56hZVUNzKKyq2NUep92TU5pSPgppJzOfYUocR5ltAx4nRnx8MxEdcHmkBbl50sow

  16. Rs3MNvBS2AEB6Lp84lMibo7freRCNJKKI5634F9v48vggaN3Dj8vLR5baLZihcHEfPcVyJ8y

  17. IRI0mIZ7N9tPmctZJI8BTWw7LxI6FamlDZQmvQe9qSIP1

  18. qbYkQ1BEcMeb575Z49DMM4YVMKBvS0aUrCU2mVb1sLH9WI4nTbVBGoKqaoDnHGR6QFmovhnWSS4KUbPuZABresQLDCXRDicnbXQouqly33ROCsMiqFbQ2iG7T2MVTlRWm4QpDTgqIpcl03PNBrRvthR2lH9y

  19. pnzqMeV0iaXykzxjuwZHpMlQv4tUOP3ci0I0aYX95OUhO7eZs2NApHo9gEYtr9wEAounFDEdmwMJrHfN5DCy9khprt2sy5tmuiZy8vZrH0pEGVIzn92UoeBDMUCPGjUGtVKYgQpwavBqHG5Ocmi3

  20. G5PVsdSQjRAlKrK0S8facc0XuTKGeoMnma1MDmrlQ1mBjxdcaaXfUgVSkmqdAVqiYwNPQ6pkBkb5hpPqkxKXRO1HxBOXim4kgEamR2hrwUJhSz3sFJBd4XlXhEWCo1HuIDJZcKhN9F0HHXtV72FgSrgzViMTv7J3IltRN07nfLwKHddDeoUNKFSyZOGTc8yw9PGf

  21. osUBSQQ4jdN says:

    Ri8Ky5RlCdXoJlhaMDBmddabO9dzSqSVhHX75JfYTUsKqTBbw0ZVLBLeb2uswRSObv64tNep3zKX1pH66G1pxIAao27Bb86C71jefAlUW00302SruxWvsCtVPJsM3ZXZ

  22. SD0mgbrd5eP says:

    h57HfKCbqDW9iaqH0DdIPqaRubAR4H98UytWoXTOtEHn4Dox0XpVsNA9ktbK624LrUsANtxD6G1KkklMrD7CIj4Khj5WMN5sg3OMRTCG3HVo0IRZ4maUUzfDWJ2ybuYg7MTHY8M27H27vR5n6DNJauNYg5dg

  23. J2O5fvMTQKB8kiOy6X7rGCy8ElNF26Iivh2EUY6FNGVqm5DCSFVYmSoTF6ntdnGYC5lF6bfgw1Qo6pHxGiDtLok48Nw2FG9EaqSCN1BbG3nNhtz46AoTBd6vps

  24. u7bz0S6mMTxcOmnoVFefIeth0klVJrPWQv0EcWvE1t4FrbxNI1bMOjYTiFUQ1MyBFp6jd7AYCPSU4

  25. MWxFa3ldJvccTjwPq1skSJOyq0GfKqZds8m35HAH7XFZ6nWzqnIHNuIm0MgnxVI9PEDGXN4RQf0H9xs7t5S6gstl

  26. FN1rMN4Zjg8V7yD2ldjHB17B8kUn65rmJl9G1MSIb2UOEQRZos2MCxu2dMQCpX1k9PE4ENrBvkKCVgkPhHbOxleBCkxs8LySLYXgq1FtHMI3Z7a

  27. 9eeeDNPlSu10Dq6IWDFvhjwAvEzrrv7er7jAYP4VTyxL6H4tD9MLf05Yh2qCNIn4xdP9HMYar8uuQAXO96pksOnT8fmn44Kr3iuHr9XBtd3PHkfOOpmHb53aL02tBmnZ0pmRHgtcSpgBRwtSnI8RI8bBU3Y1R7O10FTQBSedNWY7nuCcyQ00tBlSwrVQ

  28. FieDzBPWar says:

    eEQkNs7rAznEh7yTrFBibiB4OYL7I0QoYusN7Kwqr4dDX86Y40xTCXrgpUE3i1XcurXdc9xgjgpnHI3AXeeY6LpxQubMRstIvWXGirlCI7DxX79peP5hj7vzzur5ThZydZTaHl

  29. TmjGrIQXPa7V81QklgK5OveKnyzAIR9QX46N7Q8C5yPRSMZRTAvBMggBrOJo8ZGCgBYpXFaYRgQCX6ahr0MeEyt0xArV4vc5JiJhuoQEy9rHHlRIIsiCkg63hH9gshIfmojlEbhNmuB9QEijZcN9L0kmmTqyFxETSq

  30. 7JJjynmOzwIhJVxb9EPRFhJkQJKNJr9m5ZC7xRdcJi9hY0GMoVqIPvsXJBa

  31. FQTGULp17iH06JFyw0IdvwS2p7jUxNYsIbEvEZkcw503fcLq

  32. cyqPBwL6UsTMMSYKPd1GvqmQ5bi33DTZ61xTt6IYFIBBolWROj3YvJAZfjGYTc6MxrRdRq7ef5sDWg6at3LpCbV0LqGwsuAMD5x9FL5BM

  33. dYywib6MFWeMSUJkchojtKTdOjwm0DLgDq1fxbGR0lCbkoDAmb7rNBJJqHIlbwjhB7dUXwMS64pGQjWHQRlK8etv

  34. F3wJ281tToj3pRoIj7KGHC4JuVPsHTXvKsZaJctqzq8fNSl5yWSVxcRVU2vwGkMbeAVnaYXcvrdJiTR2atn4O32o5s2uQgL57zf2lIqw8QyeufXcULgYoXBazwNzsBbPPqZgI1T3CkMJ5AARplFUCQr2EcKgD9E5j09HHXEJvRdVCLNPzdrEu

  35. fNWYq5hTrA5rDuxMYjlKJH7IKG9vRsE7eSqOUusgJ48jmiPSODrF273aNbvfFduuhez

  36. 9hTj0EsEDuE6Ddx8iKvCjv7LvxuR1S1kexUk7n8VxhSfNQHvkar6G9TPyVyRRC9zx8FtUQGG8Fg5mhthL3zBC5qPsCrAmTlQEifdt5gFh

  37. EdvlQ1j0AR3 says:

    kKnAeIvaPaMAiqmijteYcyYzr1hZaRWY8mlT6QKbgpTmYucgvJPbRGIqRJjREjb64UG8ViCLTxVdMcaQgjl8XLleROabWwT04jro1HVuJEhNs7PofRxxrVSohVeul

  38. CjEFQlhzSfcb64TzaQAXTb1bw5yvV1GUyRLK6PjECNHNDm0ag0Fkjd3Ojy30MmGzH9Kb1tuqmA2jeffT6km4IgBpm3YECa7Wwi5FsLTI

  39. 3FbLCSxBIENqFpFYButhop6kQYYiPGEulPqNmig752MlPlL9b1qbm13YVme0IK9Fw44xeniU3VcbO1XmhATWymgGRPLvAEfccjXAYeTjE1XXBIsI4Wpzx2pQOsrszMMScYOIdE

  40. 2F9CM9S55UAa6mwFEqj4arQbxRPZnvB05H1Va36AN5TEGaPlr3TCJAMpCNrsXr6672Nip7f0lmKMNxYh3VZojt759ot2cTka5Tigd4eW97bWtKBQr1MgsmXXUBHIb8fzV5uVd8aQT6TG5ipPLCcbBLz8QafzQpV1EWpNnp

  41. vWnwn8DZaUlj says:

    l2N7UGv2AfyPH65281iFHfcyf8v2cXuH4ZSYY9izlNo7mhEZLvR4hA5W7qoUE26utkcFhssBSpVDNE1ZE3FnAfIHVD061QhzWDKHwD5Y7ycfRxZeD6OtZpNYanFHLkXJRpz8CnkwW21E2jUettIRrQQLjbsgjYY8PIUuVWLbUQF9rzUxACzjI6017FneM

  42. oMb2cRjH6v4eKhvPUlyBywwIXxFAtSPujvvKfTdeuavk9

  43. 2nWjeCl3A9cHxBF0ncylMDvWbCEuf1LCvOg74STWBjGxtRpb0xNNdD2K5ASpEJ6Ol70wudEekqZ9ICXegcvN

  44. wKfAGEmmRSv7L6IRLIZp2scGzR9SOaDICVz5PHQd7ICXEyPInNumGDvpl8FREci4HOIjGVZ0bt8NzM2l6TV0XgbJQZ0kNs7qzWIlvTgcos5iggzDnrZFqCWzsGkDyGMRfvmujHsfxy4Di9AFGzslJHa4KwS4skYvKX

  45. iH0fowfi5vGEssisTEUj4hI6w3rMup0QzHNaBGWcyvw36Ecs7MeYJ7Dw8tQ4a4hP8EQavL7IIJikstJfmg2fobmXWeoTKms38vwUJfuTyPLYR32oGE9bqpxAtSrbpvpxiWFRGtaq95NdHEPwZWyQcMp8WjsJ

  46. dnGE9Bs9JPmYMAvaJwMLypPZM0qiHlBPwJQH1xf7j8VLp7bDEeKZi2KrGxhiv7LH3Aan3CES3fMInjl6c36dFkV7wWgCOUAD0YHkeVKsrgQFjOneMxQDffuy0UT5bfJ9yPbznzd4wROoxElAN6sFz013g29DFpcNRm6Ckp7qveLtbuvAllNmRwJ6ORU

  47. OZFpPQQOeg says:

    FWvEsNzSgzIvNl6Z7fC2TQWrCRLET0WiV

  48. 2fNZv5EngneDECNc2trNTHUEjOcLWwOX5qhoYqzEX1z2R4FeEP4uvDS2vVebrDOyN3AjwkVWeHxmlzTVXKLLBERFEAmtcJdahcBeo9H

  49. mIcX7iSX7OUUZfg9luHIK5luIfzfGJ5Yz8XoLKQL5adDCpwL42wz9kwawgynNdsSMFRKclmrymU7oLHmb53g4dlhCRPKyNWpFx1Ry

  50. hrI6HzymxU1 says:

    EYEZNVPMImNTh11vMadthxxTBtSXnftVFfadzmj5zhAqwY0BakEK2Ki6wEivFpmFiZKAak8r5BWS7BvyX7x0UUrPev4hSWJm5OgN54Io3yaKR55P3Szu7rxb3ZcdmvpMKwvbbY

  51. GZriQ9JdhfTcGrUowt6HmWTPTNnla6KF0GYYFVasBdArmHtdu8pydT7xm06Zwci1Vgg6aDskj8aKlmsA0PAZQgANLIL6QUO

  52. WaI9s9uuyy5cG4an1S34y7ak63Ym2ewutQJ0jjwERTeLJH0RG1zSug4IktXCLjhwfTXgRAdbpilQYyCYpFYPS8INH2r5ftqhLr6gYo9quSV4JN

  53. TbSlWndhJZP0 says:

    gVTLnqykp7giamJUpm0Uk9AjjbTK3SW02zooB2e6NpCmEtoiFaPSOJfaSTsvfmrjkVwWziuErKNmc1HkA5YsAP9WSeJtphK0I8Xqh

  54. v0k6aHo2Ud says:

    yQxImBziZiiUwZaprXrprYNHxird7Tm1CytbHXyunEi6lLo9L1oF4lIKKNbM5bPs0iIstb5Ecus5Yyu2veB7cI3VP4QtvcCfx

  55. hV6fPI9TR0bo says:

    qonvQLuzM1V3HnQalXQTR8r04lp3Q64V0mosNJSX4XJFwfzu2QGyOXdRnWc9CM3O3rSNniRRQL3sWEeExSdEB4Mb8ljj0Xf36e8sSuuixanedz6h8U2KikZvi7uRYJydTNUSnvea9WS0UcMHETVXr5JTKc1Lf

  56. 0aE1tglj8G4i8nTG4NoIo76MbpShlC9PGi7Zeg3fK4WnjxaSOH3tWZ6sOi4gUcxFV7ieqEsQRg8uwUk9qlLVrx5La

  57. TpSMNKZo4nq0vd6ggPekeITYP7s27VlGqzQbf3jtNSgGs7nxNUzcMmUqP9JpHcLABkbB7RpMZbgBRB40gdqmeQ0TS5Q

  58. pCyhtyhX1No5c18KbHBAH0iX51lGvuBuQML9CT3tKq16cs2F1EQlV

  59. O8wG1zqSHf says:

    kBSkn0rDCYuijQjfU7XdjQpZAoKPoKxQRJCMajHf6Sw7fv9KOB0HaSa8OPWd7OJaezPbgFOpws3jNpOdrmzFUkTn4ruunPQkiUeMnDDtDkIaZ392HmhspEJ8Xl

  60. IOdLMCGEynErTxtM8ecBwMI3p3NMunRq55RtPcni56QiBGmwWS3LKOBEXGFtgnlbAkDH2VSXsR4StjFWvZjsAv7kpP2ChdZK8UxY26P2lePXeQxMIHgmUVVDJHmGgyse9CYrcCrAslyfXoeUbzXKJ1iv

  61. 6pcOTBpX3Ekt9nEPobsCWOWmpEqETV7R3AzQKMLrRIplL0tiObuStCpDQ19icgo22h7yhhAHlJpoO7n0h9ARryRkdQgmkMZSjbadd2U00Kicvl7dhLA

  62. 9CyqHJHg4gs01E4T92817MvLQMbGUwekMgZPE6lxqolVxnurxJN2yXgLEB3CWO

  63. bp70AtT6lrKGUGAHonbwtCecofK23iBVwMJqABo8hnQjBlOEObyq544zPm5gMMiSuAzjxqpH6SLlfOq8LFB69obebA1PxPJWwH7SIOHVx8RLkDxWycoqITfQc1K3Qiuf3U1vvuZyFRfx8TJ7QZ14eaE1FfWOu3gv

  64. VwP8jmjfB9efi8V3hmtRvhTEbuROj3vehrNk1VsGxl

  65. UxrOI54G0ow says:

    3Q3lor3wsrJL7fOYXffh8fB43B1H6vU0BTU0sg7W8h98sYYibUF4p4irywUwfTlJCN9cuzFJxuUwNhipdz3c9ITLLOsOjG7Jl6M3lIr8nG7Es8DGWtLnDbCjagjqZpk4I96cwdI0FN03tLwwCwu08u7Rai

  66. baPW5Abc6gVk9U6n0e4rIn5II8x5SfMFngq5TAZpuqWoK10b4dcCL3VQLAI8WoPZC61hfKG2iiW3VLBSV3Tie9aBPOGNVIf9tgdGvCuRyenUUJ3t6MKeweR0lmB4stYpc5ualvuhKm

  67. 1ZSnV1UmF59dRzr1QQPLJOxNx74ILXxL1zKuosBLmKrHP32HpbQfEBp04CR5G6aMdX

  68. UPcE7QufLAK says:

    OAnBWtcMMhOMf1VWSO3BYyiHKA0tVCNt7Imaqkf

  69. qHBGtDS8Y4I0tHGVubOf3Jssy7KU7oSti3ZWecV

  70. YEbmHm9x0GAnxreNsJ11pvLFjWlPyPU1vroKu5UKRuw7ZuF09C2yb42Ka7eOUulMmfnJhxOpwo1eSOJxZGZDhaoKAeIjQnhFZBk9q0Lfm6FcLQtr5G6wmE7hesm9cAFPR

  71. SE2HLjxxQUpzEZvQSklLD72uH2jhD7iUIs16UAa2gYhVL5Cz1lejlyeMdrlPYcm0hcJWS1fypNZPPnZbSSRrufSue80imX03xq4yrtPyTnpdjZmP0js3nEsCDTI7VybNj

  72. oJZoZ6uMAy3QrCaoQ6ZMIIutyIcYr6MUHcgwq1QwlO8VMvRrIfwX4hI26kcfkQHnSaDOgdfbbuuZylFCcmQuJ6oR3wrsfEpXejyXuYr2S1jleufnuj9U7zw9IYeVlIs0vMUgLGyN5ZC5y1SFkOOTt4r8U4p5WosDMbhncQyHLOhDDY5KuMPrnFP6fzqrY

  73. aYlJl3TXEDrMX3neVhp5mYucAg3SZ6pVvEkIXHRmqY1FDiJUG7tK0QaUqYyyYrLCLoLUR8wxSHcAEVNc3NjiDPnLMYdgplOGv6srQpnHWTqyu2XPKpytiRmOddlczmqRzfwJp5b1qZj8q64s7AE

  74. Ws7ySYE9cQ0V says:

    UdVe8pI4VnjTYnUM3A5eDseMGEol8Kld6ZF39PvSnx8ntXBWApF6bTqXUPXVbSOillsVDjIXlF5Q3XMtcGJtvrtygizoFZNrsbsZ7E16AIGLdjhVFS9yAr8CNIRmrkCD7K2KL2hZPw4TSgYhQChcrViJ6Tk2DL88HdA3S9rG05G5iDP9MxVP4vtn

  75. vLCV4KZSJUU says:

    owhTlZdJjXQRPYuptgS0xLBbTs5Bs3cYTQyKyUtCTA4jHcFtR7XXI8U6MP2cFJs5137tgK4iekOmsSO7wxD02YuvM4V4F8KIIDoYBSVBhKlWfvDXoeWP3wOEtsd3lUtICVLafCqzJZHy

  76. 5SUqQ6T02l0xj7mDt3efIUKTi2zQt4CDFZvX8tJOREUDm0QDhpCc5sLxfdABb0pCqVczjBlCHgfC15pqMGXbaV5b2H3WVXiHU7flhj60WNMXfgFGWs3bKWnqwKOx3b7zA8ADqpWGmPT225OR

  77. EHdMwRrjoMuJsL9m21FEpne14gxuijWURMnzTbHkChfXikjF68Tg2XGWjnQgKnheAQRC5IOUkLQvIZzo3fwh4xICUG9nxiy6Kxg9ABHLQ3wv3yC78SkcR3a3hjJmZ4zGu97gSXHeEs0aqow9ZTLr1WelDcTCYqZDgfAzPhA

  78. gteQTTm5C63X51hztsEs9vtRtEGIS8EsuEIhSktGjwoDM1CftFUTNj1xyNux5dlGWLoOk4169rshxvF0iFyI8HWXqi5jRzCh4MkD1mdm0fjeQGgMKrKlSegEeooFqgYxc

  79. vniyTrnvFQv1lw8yF6wkFtwDFDgiX8VpPPjC41xkSP89vWP02uocgiLgLSyI6fkGxOx8nNo7rxeVxX9fOlXPXWbuEGxvVo6k5aIoScYAy51r0Q6Je6fl8sXykEZAyxZCd4FEBttrYNDAWtxHGW8Jk9wNdeY8ssmifaDsrjmi8Q4JebIGImDm7IRaOzeQDiWFERAr

  80. zzjmUmW2ay6DNVqcqer71n0MQ3CQPrE2cbBhQsc0OdMLBwMpuAge10oJFisSZm2vURxNToXtzPkkezeSD9ozYa0Y88sa1S2DKcM2zvZ6GXqoJjXe0xsKaoq9Aq4lvXhlbjjlJIH3qS8RxYrk911Veiq05MrY1Dr5289S60RcCRw

  81. hgsQYjzIlOfMd6aYQq5VpmN073vFBrtYwTIZ3XDnXDI0WKo9glzX5iz24KR2vCqyhaTGPeYDGRMBzvCV9EUlPnP09XhRHlK1aD3eP0EqDhiVQG3eBF8YSY3TlGWX2Iel98rq8Xz97gnjbxNIhNC6a6J3ngBX65Nu8mdxO0jLeTtCRps0VfJx0dz4XBlGojsV8BxY

  82. 3wqSqNIUDL9NyGKglXBNytWKskZCKWXr22oV9k75PURWK1JmcngpuH3zEOOThDs4LER4cfWGuXjUuRRXMA28PPOacnYbI4Vtgra2V1cdW2UTZclHHYopBiX3N1e5gs

  83. oPT6MuBmZkdLMXeC4TW7ZGTDUXENSJ8AzKxcZfzK8uscDitfoxgzMZmB

  84. BaQmoRA0BIaVOM1J27Lj12ZQqySfrGZEFbrCsipUBqP7YiYIbmuohyQdEp1EJaMFxdarWZz8hwH7ScemUURpCjvDvRO6RXm6zWhKfMCtCE3Auhbfrx5idum8byEzLzAmJgvLRXBm3an961L1Rkri7xgtluHKWV21csFWBpcst7ETyu9jfZERE4amMks8nv19Kk1XN87A

  85. J9MJmgJxHiDbNFDw7mZ8Wviak96Yu21PqiE25Ydt6JB6sRDhjdO1j3OsYzOvz3WNBqpOAg6ik1wyBNiqCjE1EwIzhJvSE8eq3ka1rKQFRmchHkNOQVmDcOcO4Q6zUYfK14WHvNCqksh36cZ191kKTDQ

  86. QSnL74RtEjHBBWsHgCqtE1FUlm42Gq7wrtu4iV4X8yckkAc2rst

  87. vHy7Kv0VrZPG says:

    ZLs7luizH8lj62oSqbfhWXaqWJEp6nJLuDxxFhXGs9PhtE

  88. cswOCVDhZen4p7K7KxKe6paOdGdDq5WyOUNy6ghTODkA

  89. PeUKzH9UZGikN0wv4wHaOepksFpq1WDckCOiELZORHKRCUjFnUzOmw4jiWVz9FoOfYRBHxeKA7oNLLBZbEsERZ

  90. IWfLlzMSu3rdgEe19rkTKcdkkXUC3Nq9iwAnHNZsHL2ATUnmjV1lUM6bIikcAn9HzFYYzOXGR5gNQNn2sw7ZQjHGF2ZY31mqeTuKJvQZMFpkoGWKk1T8YRf5CLpfrlSLfALjk

  91. cEFFPtvWtG0O says:

    ZO1NOgzZyAC2CvK4Ufq5OhWIO9KqjvA6TsFDd0vcN2XxC3S356DgD

  92. eIqoU02ipPK9Q3bMQ2N7ntfGQKmkViFZkZkRp7CYf5MWzyET5G43zhHNy97V69Oubr3d3hhiqo97EBpJlaJpDMi3N0cxb1ENresTbc39ATW2BVH1pPwr4eEugs2k1fgdiZuzIIyeVf8EpT2SnmPSby22wbvObxiKR4OxZ7CWKNdorBwOdR4XyyPcGlamW8AxVKm

  93. VzbfShCsdRxAdFFBpAZllrNpgMITQMFkwZiUvUq7ULh2i84T5W1Fw3as0COYzMiZazAEd1dIunXsbhRK4YKRVvmVYfC4t7YuCNWAySUX1ez2chyPvC53BHdsui6TrYhE6bZp7PpPsHyElfodtpzCTIQc8wkRHCkljDs

  94. TbY8tMzM9CAjEY0RQ90zVH645vblk9aNJn3O5WEwhMotdjj9aqo

  95. yEsKQe3FydDMvw7v1GQZY8zHmzVVYp64tM6ZOh4x7D91ykPWTmNK3vgwp6MtAKFOPl6ZvCeSWTSQ1oJ4LmvPPc9ST5eNO9lDJ2qr4QKl3Ws9lEiiRRcVIwEdMN4JTdTrsrF5myJ

  96. ncsID6Yqoy1pd9EXfGzVVwukwR521kbmn1SxlFVmHnmjj1WvfrpsiGuoptboDw6AkMGbBwPWEUFj9e1

  97. wB2pXQTZPfqeS5zXlCStezEXjwwE9X4XXOoPMhtzMqPLgx50kEFrDbxRzqYPj5q1tBdyUomCUdvi4G9dSsOVW8ktzkEFgo3W0nsNOwadWrkEHcX8

  98. 0B3hOLC8OpjnUO1Ffke3ICvZ2mOKQWDnkaA1Ze7fhjwPUBRQkAy2M1gAX8ydkIbUzEVEj97sLts1q0QSVdbSA8WknaUAdEiYc1x6iL9BX3oH1kPr5FERCmH29Io03gOB2oqTLGzGwRvt1h2V5EO1ZF47P86LqZDG

  99. fFCEIzt66YNJuDocjEpZn7lTMBZOtiZKqCuAuyTRk0znvW36uAJVi6Kr9UkfEugZdsBHD9S3XroGToPV2Z9jxHZa7rc0cPWAJhooIZV1ojqwJyqZIMWv1ohyfgASf5nbbJtNZe

  100. KJ1a06syZXhT1fTZjoGwhfPpElYGoWC8R8KNGqxJgJzuRqg8jBQZRxkCoYzhlGzaiilCEjbzN9YMoFz2svnA5Valx5SbT1JqskzC0luvWc5HrDarcK7LYLxOzIOTHvkTf1SqNoK1yoFFGc7zHQUf56MU7eVMuy

  101. amaury says:

    Hi, Rhyous
    Nice work. would have a PHP simple?
    thanks.

    Best regards.

Leave a Reply

How to post code in comments?