Files
svc-api-x/v1/etc/info/AJAX Authentication with Taffy REST API - Greg Moser.html
T
2024-10-23 11:17:42 +03:00

900 lines
52 KiB
HTML

<!DOCTYPE html>
<!-- saved from url=(0113)https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/ -->
<html class="no-js"><!--<![endif]--><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/cb=gapi.loaded_1" async=""></script><script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/cb=gapi.loaded_0" async=""></script><script type="text/javascript" async="" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/plusone.js.Без названия"></script><script type="text/javascript" async="" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/ga.js.Без названия"></script><script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/analytics.js.Без названия" type="text/javascript"></script>
<script type="text/javascript">window.addEventListener('DOMContentLoaded',function(){var v=archive_analytics.values;v.service='wb';v.server_name='wwwb-app57.us.archive.org';v.server_ms=337;archive_analytics.send_pageview({});});</script><script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/playback.bundle.js.Без названия" charset="utf-8"></script>
<script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/wombat.js.Без названия" charset="utf-8"></script>
<script type="text/javascript">
__wm.init("https://web.archive.org/web");
__wm.wombat("http://www.gregmoser.com:80/blog/ajax-authentication-with-taffy-rest-api/","20130907051536","https://web.archive.org/","web","/_static/",
"1378530936");
</script>
<link rel="stylesheet" type="text/css" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/banner-styles.css">
<link rel="stylesheet" type="text/css" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/iconochive.css">
<!-- End Wayback Rewrite JS Include -->
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
Remove this if you use the .htaccess -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>AJAX Authentication with Taffy REST API - Greg Moser</title>
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="Greg Moser">
<meta name="generator" content="Mura CMS 6.0">
<meta property="fb:app_id" content="181578861907653">
<!-- Mobile viewport optimized: j.mp/bplateviewport -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Place favicon.ico & apple-touch-icon.png in the root of your domain and delete these references -->
<link rel="shortcut icon" href="https://web.archive.org/web/20130907051536im_/http://www.gregmoser.com/default/includes/themes/gregmoser/images/favicon.ico">
<link rel="apple-touch-icon" href="https://web.archive.org/web/20130907051536im_/http://www.gregmoser.com/default/includes/themes/gregmoser/images/apple-touch-icon.png">
<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/style.css">
<link rel="stylesheet" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/960.css">
<link rel="stylesheet" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/site.css">
<!-- Uncomment if you are specifically targeting less enabled mobile browsers
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=2"> -->
<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/modernizr-1.6.min.js.Без названия"></script>
<link rel="alternate" type="application/rss+xml" title="Greg Moser - Blog" href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/tasks/feed/?feedID=4636544F-31C2-4C50-95B9532D6DAB7E45">
<script type="text/javascript">
<!--
!window.jQuery && document.write(unescape('%3Cscript type="text/javascript" src="/default/jquery/jquery.js"%3E%3C/script%3E'))
//-->
</script><script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/jquery.js.Без названия"></script> <script type="text/javascript">
var dtExample="11/10/2018";
var dtCh="/";
var dtFormat =[0,1,2];
var dtLocale="en-US";
</script>
<script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/global.min.js.Без названия"></script>
<script type="text/javascript">
var loginURL="?display=login";
var siteid="default";
var siteID="default";
var context="";
var jslib="jquery";
var assetpath="/default";
var themepath="/default/includes/themes/gregmoser";
var htmlEditorType="";
var rb="en";
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-11846667-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://web.archive.org/web/20130907051536/https://ssl' : 'https://web.archive.org/web/20130907051536/http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<link rel="stylesheet" type="text/css" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/shCore.css">
<link rel="stylesheet" type="text/css" href="./AJAX Authentication with Taffy REST API - Greg Moser_files/shThemeDefault.css">
<script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/cffp.js.Без названия"></script><script type="text/javascript">
var dheight = 0;
var nheight = 0;
$(document).ready(function () {
dheight = $("div#wrapper").height();
$(window).scroll(function () {
nheight = $("#rightNav").height();
var y = $(window).scrollTop();
var trigger = dheight - 335 - nheight;
if(y >= trigger) {
$("#rightNav").css('top', trigger + 55);
$("#rightNav").css('position', 'absolute');
} else {
$("#rightNav").css('top', '55px');
$("#rightNav").css('position', 'fixed');
}
});
});
function toggleSubNav(callerLink) {
$("ul#navPrimary li ul").hide('fast');
var targetUL = "li#" + $(callerLink).parent().attr('id') + " ul";
$(targetUL).show('fast');
}
</script></head>
<body lang="en" id="blog" class="twoColSL depth3" data-twttr-rendered="true"><!-- BEGIN WAYBACK TOOLBAR INSERT -->
<style type="text/css">
body {
margin-top:0 !important;
padding-top:0 !important;
/*min-width:800px !important;*/
}
</style>
<script>__wm.rw(0);</script>
<div id="wm-ipp-base" lang="en" style="display: block; direction: ltr;">
</div><div id="donato" style="position: relative; width: 100%; height: 318px;">
<div id="donato-base" style="height: 318px;">
<iframe id="donato-if" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/donate.html" scrolling="no" frameborder="0" style="width:100%; height:100%">
</iframe>
</div>
</div><script type="text/javascript">
__wm.bt(625,27,25,2,"web","http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/","20130907051536",1996,"/_static/",["/_static/css/banner-styles.css?v=bsmaklHF","/_static/css/iconochive.css?v=qtvMKcIJ"]);
__wm.rw(1);
</script>
<!-- END WAYBACK TOOLBAR INSERT -->
<div id="wrapper">
<div id="header">
<div class="container_16">
<div class="grid_10">
<ul id="crumbList">
<li class="first"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/">Home</a></li><li class="">&nbsp;»&nbsp;<a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/">BLOG</a></li><li class="last">&nbsp;»&nbsp;<a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/">AJAX Authentication with Taffy REST API</a></li>
</ul>
&nbsp;
</div>
<div class="headerSearch grid_6">
<form action="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/default/index.cfm" id="searchForm">
<fieldset>
Search: <input type="text" name="Keywords" id="txtKeywords" class="text" value="">
<input type="hidden" name="display" value="search">
<input type="hidden" name="newSearch" value="true">
<input type="hidden" name="noCache" value="1">
</fieldset>
</form>
</div>
</div>
</div>
<div id="container" class="sysAjaxAuthenticationWithTaffyRestApi container_16">
<div id="main" role="main" class="grid_11">
<h1>
AJAX Authentication with Taffy REST API
<span class="credits">By: Greg Moser</span>
<div class="likeLogos">
<ul>
<li><iframe src="./AJAX Authentication with Taffy REST API - Greg Moser_files/like.html" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:45px; height:60px;" allowtransparency="true"></iframe></li>
<li><div style="position: absolute; width: 450px; left: -10000px;" id="___plusone_0"><iframe frameborder="0" hspace="0" marginheight="0" marginwidth="0" scrolling="no" style="position:absolute;top:-10000px;width:450px;margin:0px;border-style:none" tabindex="0" vspace="0" width="100%" id="I0_1378530948757" name="I0_1378530948757" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/fastbutton.html" allow="autoplay &#39;self&#39;; fullscreen &#39;self&#39;" data-gapiattached="true"></iframe></div><g:plusone size="tall" data-gapiscan="true" data-onload="true" data-gapistub="true"></g:plusone></li>
<li><iframe allowtransparency="true" frameborder="0" scrolling="no" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/tweet_button.1378258117.html" class="twitter-share-button twitter-count-vertical" title="Twitter Tweet Button" data-twttr-rendered="true" style="width: 55px; height: 62px;"></iframe><script type="text/javascript" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/widgets.js.Без названия"></script></li>
</ul>
<!-- Place this tag after the last plusone tag -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://web.archive.org/web/20130907051536/https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</div>
</h1>
<div class="content">
<p>A couple of weeks ago I was working with <a href="https://web.archive.org/web/20130907051536/http://www.blogonria.com/" target="_blank">Sumit Verma</a> on securing the Taffy REST API that we have implemented for <a href="https://web.archive.org/web/20130907051536/http://www.getslatwall.com/" target="_blank">Slatwall eCommerce</a>. &nbsp;While there are tons of resources online about different methodologies for REST authentication, we were having a hard time finding a deffinitive "best practice". &nbsp;Most of the time when people talk about REST authentication they talk about 3rd party services using the API over HTTP in some form or another. &nbsp;However there is an additional ussage for our Taffy API, and that is to provide a solid backbone for all of our AJAX requests. &nbsp;With that in mind here is the solution that I came up with for our REST authentication.</p>
<p>With the 3rd party service access, we want to hand over an API key along with password to give them access to a selected subset of resources. &nbsp;However with AJAX we want to give access to any resource a developer wants as long as the developer has given explicet permission for the view to use that resource via AJAX.</p>
<p>Originally we talked about generating an new API key on every request and storing it in the session. &nbsp;Then on the Taffy requests, we would check the session to make sure that the API key exisits and the proceed with serving up the JSON. &nbsp;The problem with having a single API key for a user is that it doesn't actually define which resources they have access to. &nbsp;The end user could just view the source copy the API key, and then use it for whatever they like. &nbsp;What I really wanted to do is programatically create a API key on the fly that is only valid for a single users session, and for a single resource / method... so here is how it works.</p>
<p>First we create two methods to generate and validate API keys on the fly:</p>
<div><div id="highlighter_62440" class="syntaxhighlighter cf"><div class="toolbar"><span><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div><div class="line number14 index13 alt1">14</div><div class="line number15 index14 alt2">15</div><div class="line number16 index15 alt1">16</div><div class="line number17 index16 alt2">17</div><div class="line number18 index17 alt1">18</div><div class="line number19 index18 alt2">19</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cf plain">public string function getAPIKey(required string resource, required string verb) {</code></div><div class="line number2 index1 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">var apiKey = </code><code class="cf functions">hash</code><code class="cf plain">(</code><code class="cf string">"#now()##lcase(arguments.resource)##lcase(arguments.verb)#"</code><code class="cf plain">);</code></div><div class="line number3 index2 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">session.APIKeys[ apiKey ] = {resource=arguments.resource, verb=arguments.verb};</code></div><div class="line number4 index3 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return apiKey;</code></div><div class="line number5 index4 alt2"><code class="cf plain">}</code></div><div class="line number6 index5 alt1">&nbsp;</div><div class="line number7 index6 alt2"><code class="cf plain">public boolean function verifyAPIKey(required string resource, required string verb, required string apiKey) {</code></div><div class="line number8 index7 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">var sessionAPIKeys = getValue(</code><code class="cf string">"apiKeys"</code><code class="cf plain">, </code><code class="cf functions">structNew</code><code class="cf plain">());</code></div><div class="line number9 index8 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">if(</code><code class="cf functions">structKeyExists</code><code class="cf plain">(session.APIKeys, arguments.apiKey)) {</code></div><div class="line number10 index9 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">try {</code></div><div class="line number11 index10 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">if(session.APIKeys[arguments.apiKey].resource == arguments.resource &amp;&amp; sessionAPIKeys[arguments.apiKey].verb == arguments.verb) {</code></div><div class="line number12 index11 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return true;</code></div><div class="line number13 index12 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">}</code></div><div class="line number14 index13 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">} catch(</code><code class="cf color1">any</code> <code class="cf plain">e){</code></div><div class="line number15 index14 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return false;</code></div><div class="line number16 index15 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">}</code></div><div class="line number17 index16 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">}</code></div><div class="line number18 index17 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return false;</code></div><div class="line number19 index18 alt2"><code class="cf plain">}</code></div></div></td></tr></tbody></table></div></div>
<p>As you can see, all we are doing is generating an api key that is unique to this session with a specific resource and a specific REST verb. Now all we need to do is generate this API key when we are setting up our jQuery or Javascript like this:</p>
<div><div id="highlighter_965634" class="syntaxhighlighter js"><div class="toolbar"><span><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="js plain">jQuery.ajax({</code></div><div class="line number2 index1 alt1"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">type: </code><code class="js string">'post'</code><code class="js plain">,</code></div><div class="line number3 index2 alt2"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">url: </code><code class="js string">'/plugins/Slatwall/api/index.cfm/product/#variables.productID#/'</code><code class="js plain">,</code></div><div class="line number4 index3 alt1"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">data: {apiKey: </code><code class="js string">'#getAPIKey('</code><code class="js plain">product</code><code class="js string">', '</code><code class="js plain">post</code><code class="js string">')#'</code><code class="js plain">},</code></div><div class="line number5 index4 alt2"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">dataType: </code><code class="js string">"json"</code><code class="js plain">,</code></div><div class="line number6 index5 alt1"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">context: document.body,</code></div><div class="line number7 index6 alt2"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">success: </code><code class="js keyword">function</code><code class="js plain">(r) {</code></div><div class="line number8 index7 alt1"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js comments">// do something with results</code></div><div class="line number9 index8 alt2"><code class="js spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="js plain">}</code></div><div class="line number10 index9 alt1"><code class="js plain">});</code></div></div></td></tr></tbody></table></div></div>
<p>Now we have a request being made to the taffy API that has a unique API key for a specific resource and verb. Also, that API key has been stored in the session so that when Taffy gets the request it can check the current session to make sure that the API key exists. In order to actually do the validation we use the taffy's built in onTaffyRequest() method:</p>
<div><div id="highlighter_569187" class="syntaxhighlighter cf"><div class="toolbar"><span><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/#" class="toolbar_item command_help help">?</a></span></div><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="gutter"><div class="line number1 index0 alt2">1</div><div class="line number2 index1 alt1">2</div><div class="line number3 index2 alt2">3</div><div class="line number4 index3 alt1">4</div><div class="line number5 index4 alt2">5</div><div class="line number6 index5 alt1">6</div><div class="line number7 index6 alt2">7</div><div class="line number8 index7 alt1">8</div><div class="line number9 index8 alt2">9</div><div class="line number10 index9 alt1">10</div><div class="line number11 index10 alt2">11</div><div class="line number12 index11 alt1">12</div><div class="line number13 index12 alt2">13</div></td><td class="code"><div class="container"><div class="line number1 index0 alt2"><code class="cf plain">public </code><code class="cf color1">any</code> <code class="cf plain">function onTaffyRequest(string verb, string cfc, struct requestArguments, string mimeExt, struct headers) {</code></div><div class="line number2 index1 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">var apiKey = </code><code class="cf string">""</code><code class="cf plain">;</code></div><div class="line number3 index2 alt2">&nbsp;</div><div class="line number4 index3 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">if(</code><code class="cf functions">structKeyExists</code><code class="cf plain">(arguments.requestArguments, </code><code class="cf string">"apiKey"</code><code class="cf plain">)){</code></div><div class="line number5 index4 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">apiKey = arguments[3].apiKey;</code></div><div class="line number6 index5 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">}</code></div><div class="line number7 index6 alt2">&nbsp;</div><div class="line number8 index7 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">if(request.context.$.slatwall.getService(</code><code class="cf string">"sessionService"</code><code class="cf plain">).verifyAPIKey(resource=arguments.cfc, verb=arguments.verb, apiKey=apiKey)){</code></div><div class="line number9 index8 alt2"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return true;</code></div><div class="line number10 index9 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">}</code></div><div class="line number11 index10 alt2">&nbsp;</div><div class="line number12 index11 alt1"><code class="cf spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="cf plain">return </code><code class="cf functions">createObject</code><code class="cf plain">(</code><code class="cf string">"component"</code><code class="cf plain">, </code><code class="cf string">"taffy.core.nativeJsonRepresentation"</code><code class="cf plain">).noData().withStatus(403);</code></div><div class="line number13 index12 alt2"><code class="cf plain">}</code></div></div></td></tr></tbody></table></div></div>
<p>And that is it, with no more than about 30 lines of code we have a REST API that block all requests with the exception of AJAX code that is generated on the server itself.</p>
<p>&nbsp;</p>
<div id="svComments">
<a name="comments"></a>
<h3>Comments</h3>
<dl class="first" id="comment-06890B7E-D038-6FDF-6141C2586A31A32F">
<dt class="avatar"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/5951a17e5152bfdcd1e2e6612ea33d86.jpg" align="left"></dt>
<dt class="name">
<a href="https://web.archive.org/web/20130907051536/http://www.cfcoffee.co.uk/" target="_blank">Glyn Jackson</a>
<span class="dateTime">Posted: September 9, 2011, 10:48 AM</span>
</dt>
<dd class="comment">
<p>Hi Greg,</p><p></p><p>Great post, but for 3rd parties i.e. a desktop app or mobile app how would this work securely. Have you looked at full oAuth? @ oauth.riaforge.org </p><p></p><p>I am just wondering why you took the direction you did and not a full oAuth implementation? You could still work in your solution for site requests without the user having to approve.</p>
</dd>
</dl>
<dl class="" id="comment-0941E751-AAB3-F0E6-DE27AA342A0893FF">
<dt class="avatar"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/5951a17e5152bfdcd1e2e6612ea33d86.jpg" align="left"></dt>
<dt class="name">
<a href="https://web.archive.org/web/20130907051536/http://www.cfcoffee.co.uk/" target="_blank">Glyn Jackson</a>
<span class="dateTime">Posted: September 9, 2011, 12:16 PM</span>
</dt>
<dd class="comment">
<p>also in your example you show a function called getValue() I take it this just exists/searches the session?</p><p></p><p>PS, now I have had time to play on a internal API here at work your solutions knida works better. However I still keep an Basic authentication system for apps not running in a browser. i.e.</p><p></p><p>public any function authenticateReuqest(required string verb,required string cfc,required struct requestArguments,required struct requestHeaders) {</p><p>&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Check for Authorisation headers</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(not structkeyexists(arguments.requestHeaders,"Authorization")) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return createAuthenticationRequiredMessage("Authentication Required");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Check Authorization valid</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.apiAccess=retrieveApiUserFromAuthorizationHeader(arguments.requestHeaders["Authorization"]);</p><p>&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(not len(local.apiAccess)) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return createAuthenticationRequiredMessage("Invalid login credentials provided");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(local.apiAccess eq true) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return createAuthenticationRequiredMessage("Invalid login credentials provided");</p><p>&nbsp;&nbsp;&nbsp;}</p>
</dd>
</dl>
<dl class="" id="comment-0B022D3D-CEFB-EB43-7E001140D63BFABF">
<dt class="avatar"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/5951a17e5152bfdcd1e2e6612ea33d86.jpg" align="left"></dt>
<dt class="name">
<a href="https://web.archive.org/web/20130907051536/http://www.cfcoffee.co.uk/" target="_blank">Glyn Jackson</a>
<span class="dateTime">Posted: September 9, 2011, 12:17 PM</span>
</dt>
<dd class="comment">
<p>public any function createAuthenticationRequiredMessage(string message) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.bodyContent=structnew();</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.returnHeaders=structnew();</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.reponseObject=createObject("component","taffy.core.genericRepresentation");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bodycontent.msg=arguments.message;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;structinsert(local.returnHeaders,"WWW-Authenticate","Basic realm=""FlipScape API - #arguments.message#""");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return reponseObject.setData(local.bodyContent).withStatus(401).withHeaders(local.returnHeaders);</p><p>&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;public any function retrieveApiUserFromAuthorizationHeader(required string authorizationHeader) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.decodedAuthHeader=tostring(tobinary(listlast(arguments.authorizationHeader," ")));</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.username=ListFirst(local.decodedAuthHeader,":");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.password=Listlast(local.decodedAuthHeader,":");</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return validateLoginCredentials(local.username,local.password);</p><p>&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;</p><p>&nbsp;&nbsp;&nbsp;public any function validateLoginCredentials(required string login,required string password) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local.result=getDAO().readByUserNameandPassword(arguments.login,arguments.password);</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// If we have a match return true</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!isNull(local.result)) {</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Default is always false.</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return False;</p><p>&nbsp;&nbsp;&nbsp;}</p>
</dd>
</dl>
<dl class="" id="comment-B16576CC-ECEE-1EB4-C5A8D8CE3AA8A6C8">
<dt class="avatar"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/a0572373c82e428eca2216ec31ec580c.jpeg" align="left"></dt>
<dt class="name">
<a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/" target="_blank">Greg Moser</a>
<span class="dateTime">Posted: September 12, 2011, 5:53 PM</span>
</dt>
<dd class="comment">
<p>@Glyn you are correct that this type of authentication is just for AJAX request from the same site that is using the API. In addition to this methodology we are also implementing two other authentications.</p><p></p><p>1) Full oAuth for people that would like to use a user account from a separate site as their credentials for this platform, as well as use the services from the other site.</p><p></p><p>2) Standard API access with a Username / Password type setup where you give 3rd party applications long term access to specific resources in your API. Think of how you would access a service like authorize.net or UPS.com where you get a UN, PW, API Key to access certain API tools they offer.</p><p></p><p>Hopefully in future weeks I will have time to blog about those other two methods of authentication with Taffy.</p><p></p><p>-Greg</p>
</dd>
</dl>
<dl class="last" id="comment-0A23D50A-EF7D-A418-7D94F8244C6AA33E">
<dt class="avatar"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/5951a17e5152bfdcd1e2e6612ea33d86.jpg" align="left"></dt>
<dt class="name">
<a href="https://web.archive.org/web/20130907051536/http://www.cfcoffee.co.uk/" target="_blank">Glyn Jackson</a>
<span class="dateTime">Posted: September 14, 2011, 11:17 AM</span>
</dt>
<dd class="comment">
<p>Sounds good I have been looking at this too for another project below is a signing method for a 2 leg oAuth process.</p><p></p><p><a href="https://web.archive.org/web/20130907051536/https://gist.github.com/1216243" target="_blank">https://gist.github.com/1216243</a></p><p></p><p>Looking forward to hearing how you guys have done this.</p><p></p><p>Glyn</p>
</dd>
</dl>
<form id="postcomment" method="post" name="addComment" action="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/?nocache=1" onsubmit="return validate(this);" novalidate="novalidate" data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Post a Comment</legend>
<ol>
<li class="req">
<label for="txtName">Name <ins>(Required)</ins></label>
<input id="txtName" name="name" type="text" size="38" class="text" maxlength="50" required="true" message="The &#39;Name&#39; field is required." value="">
</li>
<li class="req">
<label for="txtEmail">Email <ins>(Required)</ins></label>
<input id="txtEmail" name="email" type="text" size="38" class="text" maxlength="50" required="true" message="The &#39;Email&#39; field is required, but is not used for communications or distribution of any sort." value="">
</li>
<li>
<label for="txtUrl">URL</label>
<input id="txtUrl" name="url" type="text" size="38" class="text" maxlength="50" value="">
</li>
<li class="req">
<label for="txtComment">Comment <ins>(Required)</ins></label>
<textarea id="txtComment" name="comments" message="The &#39;Comment&#39; field is required." cols="30" rows="20" required="true"></textarea>
</li>
<li class="controlgroup">
<label for="txtRemember">Remember My Information</label>
<input type="checkbox" id="txtRemember" name="remember" value="1">
</li>
<li class="controlgroup">
<label for="txtSubscribe">Subscribe</label>
<input type="checkbox" id="txtSubscribe" name="subscribe" value="1">
</li>
<li>
<input type="hidden" name="useProtect" value="true">
<input id="fpED4C3C8E-092F-4CD5-8B2653001F73C1D2" type="hidden" name="formfield1234567891" class="cffp_mm" value="21">
<input id="fp8235DD0D-F27E-4F4E-AFB4EF59379C385B" type="hidden" name="formfield1234567892" class="cffp_kp" value="">
<input id="fp21141DAE-0112-48D7-AE2A45A35ADF9090" type="hidden" name="formfield1234567893" value="39871113,19791742">
<span style="display:none">Leave this field empty <input id="fp6C2D69E2-F639-46B5-BF693196B1041766" type="text" name="formfield1234567894" value=""></span>
</li>
</ol>
</fieldset>
<div class="buttons">
<p class="required">Required Field</p>
<input type="hidden" name="returnURL" value="http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/">
<input type="hidden" name="commentid" value="A53716AF-94DE-400E-82DCE1C50E5CE0CE">
<input type="hidden" name="linkServID" value="893339F1-0BB8-8021-68FB6CAB2F8A2711">
<input type="submit" class="submit" name="submit" value="Submit">
</div>
</form>
</div>
</div>
</div>
<div id="rightNav" class="navContainer grid_5">
<div class="top">
<img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/a0572373c82e428eca2216ec31ec580c.jpeg" alt="Greg Moser&#39;s Headshot" align="right">
<h2>Greg Moser</h2>
<span class="location">Encinitas, Ca</span>
</div>
<div class="main">
<ul id="navPrimary" class="testClass">
<li class="first" id="navHome"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/">Home</a></li>
<li id="navProjects"><a href="javascript:;" onclick="toggleSubNav( this );">Projects</a>
<ul>
<li class="first" id="navNytroMultisport"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/projects/nytro-multisport/">Nytro Multisport</a></li>
<li class="last" id="navSlatwall"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/projects/slatwall/">Slatwall</a></li>
</ul></li>
<li class="current" id="navBlog"><a href="javascript:;" class="current" onclick="toggleSubNav( this );">BLOG</a>
<ul>
<li class="first" id="navHothExceptionManagementToolForMura"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/hoth-exception-management-tool-for-mura/">Hoth Exception Management Tool for Mura</a></li>
<li id="navAbstractRestfulOrmServiceFactoryWithTaffy"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/abstract-restful-orm-service-factory-with-taffy/">Abstract RESTful ORM &amp; Service Factory with Taffy</a></li>
<li class="current" id="navAjaxAuthenticationWithTaffyRestApi"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/ajax-authentication-with-taffy-rest-api/" class="current">AJAX Authentication with Taffy REST API</a></li>
<li id="navHowIGotStartedInColdfusion"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/how-i-got-started-in-coldfusion/">How I got started In Coldfusion.</a></li>
<li id="navSlatwallOpenSourceCfmlEcommerceIsHere"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/slatwall-open-source-cfml-ecommerce-is-here/">Slatwall, open source CFML eCommerce is here!</a></li>
<li id="navUrlToolsPluginForMura"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/url-tools-plugin-for-mura/">URL Tools Plugin for Mura</a></li>
<li id="navColdfusionOrmTablePerClassHierarchyTipsTricks"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/orm-table-per-class-hierarchy-tips-tricks/">Coldfusion ORM Table Per Class Hierarchy, Tips &amp; Tricks</a></li>
<li id="navIntroducingmuraManagerPluginbeta"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/introducing-mura-manager-plug-in-beta/">Introducing "mura Manager" Plug-In (beta)</a></li>
<li id="navFinallyANewLookForThisWebsite"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/finally-a-new-look-for-this-website/">Finally, A New Look for This Website.</a></li>
<li id="navWhereDidMyMuraPluginsGo"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/where-did-my-mura-plug-ins-go/">Where did my Mura Plug-ins Go?</a></li>
<li id="navFw1AjaxAdapter"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/fw1-ajax-adapter/">FW/1 Ajax Adapter</a></li>
<li id="navSlatwallTake2"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/slatwall-take-2/">Slatwall... Take 2</a></li>
<li id="navANewToolForManagingAndDisplayingDataInColdfusion"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/a-new-tool-for-managing-and-displaying-data-in-coldfusion/">A New Tool for Managing and Displaying Data in ColdFusion</a></li>
<li id="navSlatwallGoesLiveForNytrocomNowWhat"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/slatwall-goes-live-for-nytrocom-now-what/">Slatwall goes live for Nytro.com... now what?</a></li>
<li id="navAddFrontEndFunctionalityToMuraPlugins"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/add-front-end-functionality-to-mura-plugins/">Add Front End Functionality to Mura Plugins</a></li>
<li id="navMuraUrlRedirectsPlugin"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/mura-url-redirects-plug-in/">Mura URL Redirects Plug-In</a></li>
<li id="navGoAheadPushTheButton"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/go-ahead-push-the-button/">Go Ahead, Push the Button!</a></li>
<li id="navLogitechV450MouseItsAmazing"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/logitech-v450-mouse-ite28099s-amazing/">Logitech V450 Mouse? It?s Amazing</a></li>
<li class="last" id="navWhatIsAserverAnyway"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/blog/what-is-a-e2809cservere2809d-anyway/">What is a 'Server' Anyway?</a></li>
</ul></li>
<li id="navToolsResources"><a href="javascript:;" onclick="toggleSubNav( this );">Tools &amp; Resources</a>
<ul>
<li class="first" id="navBounce"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/bounce/">Bounce</a></li>
<li id="navFilezilla"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/filezilla/">FileZilla</a></li>
<li id="navJing"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/jing/">Jing</a></li>
<li id="navJinto"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/jinto/">JInto</a></li>
<li id="navLinkShellExtension"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/link-shell-extension/">Link Shell Extension</a></li>
<li id="navMura"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/mura/">Mura</a></li>
<li id="navMuraTools"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/mura-tools/">Mura Tools</a></li>
<li id="navNotepad"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/notepad-/">Notepad ++</a></li>
<li id="navPencilProject"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/pencil-project/">Pencil Project</a></li>
<li id="navTinEye"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/tin-eye/">Tin Eye</a></li>
<li class="last" id="navXobni"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/resources/xobni/">Xobni</a></li>
</ul></li>
<li class="last" id="navAbout"><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/about-me/">About</a></li>
</ul>
</div>
<div class="bottom">
<ul class="connectIcons">
<li><a href="https://web.archive.org/web/20130907051536/http://www.facebook.com/gmoserj" title="Greg Moser on Facebook (gmoserj)" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/facebook_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/http://twitter.com/gregmoser1" title="Greg Moser on Twitter (@gregmoser1)" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/twitter_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/https://plus.google.com/113357202869560422273" title="Greg Moser on Google Plus" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/googleplus_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/http://www.linkedin.com/in/gregmoser" title="Greg Moser on LinkedIn" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/linkedin_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/skype:gregmoser1?call" title="Contact Greg Moser on Skype (gregmoser1)" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/skype_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/mailto:greg@gregmoser.com" title="Contact Greg Moser via Email (greg@gregmoser.com)" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/email_32.png"></a></li>
<li><a href="https://web.archive.org/web/20130907051536/http://www.gregmoser.com/tasks/feed/?feedID=4636544F-31C2-4C50-95B9532D6DAB7E45" title="Follow Greg Moser&#39;s Blog RSS Feed" target="_blank"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/rss_32.png"></a></li>
</ul>
</div>
<div class="subBottom">
<a href="https://web.archive.org/web/20130907051536/http://www.cfobjective.com/" target="_blank"><img border="0" height="125" width="125" alt="" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/CFObjective_speaker_125x125.png"></a>
</div>
</div>
</div>
<!-- end of #container -->
</div>
<div id="footer">
<div class="container_16">
<div class="grid_16 footerBox right" style="text-align:right;">
<p style="margin-top:90px;">
<a href="https://web.archive.org/web/20130907051536/http://www.getmura.com/"><img src="./AJAX Authentication with Taffy REST API - Greg Moser_files/pbm-bug-lt-brdr.gif" align="right" alt="Mura Badge"></a><br><br>
Copyright © 2013, Greg Moser<br>
</p>
</div>
</div>
</div>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shCore.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushAppleScript.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushAS3.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushBash.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushColdFusion.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushCpp.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushCSharp.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushCss.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushDelphi.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushDiff.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushErlang.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushGroovy.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushJava.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushJavaFX.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushJScript.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushPerl.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushPhp.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushPlain.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushPowerShell.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushPython.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushRuby.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushSass.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushScala.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushSql.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushVb.js.Без названия" type="text/javascript"></script>
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/shBrushXml.js.Без названия" type="text/javascript"></script>
<script type="text/javascript">SyntaxHighlighter.all();</script>
<!-- Javascript at the bottom for fast page loading -->
<!-- Grab Google CDN's jQuery. fall back to local if necessary -->
<script src="./AJAX Authentication with Taffy REST API - Greg Moser_files/jquery.js(1).Без названия"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.4.js"%3E%3C/script%3E'))</script>
<!--[if lt IE 7 ]>
<script src="js/libs/dd_belatedpng.js"></script>
<script>DD_belatedPNG.fix('img, .png_bg'); // Fix any <img> or .png_bg bg-images. Also, please read goo.gl/mZiyb </script>
<![endif]-->
<!--
FILE ARCHIVED ON 05:15:36 Sep 07, 2013 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 01:58:28 Dec 09, 2020.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->
<!--
playback timings (ms):
esindex: 0.013
CDXLines.iter: 22.884 (3)
exclusion.robots: 0.381
PetaboxLoader3.resolve: 27.195
PetaboxLoader3.datanode: 245.599 (4)
captures_list: 176.036
LoadShardBlock: 147.58 (3)
exclusion.robots.policy: 0.366
RedisCDXSource: 0.752
load_resource: 143.574
--><iframe name="oauth2relay2046356593" id="oauth2relay2046356593" src="./AJAX Authentication with Taffy REST API - Greg Moser_files/postmessageRelay.html" style="width: 1px; height: 1px; position: absolute; left: -100px;" allow="autoplay &#39;self&#39;; fullscreen &#39;self&#39;"></iframe></body></html>