refactor all the spa api stuff

This commit is contained in:
Matias Woloski 2013-11-21 18:12:10 -03:00
Родитель 2d2641c8a0
Коммит d9f6a4d8cb
19 изменённых файлов: 146 добавлений и 133 удалений

5
app.js
Просмотреть файл

@ -247,9 +247,12 @@ var appendTicket = function (req, res, next) {
});
};
var includes = require('./includes/includes');
includes.init(path.join(__dirname, '/docs/includes'));
var docsapp = new markdocs.App(__dirname, '', app);
docsapp.addPreRender(function(req, res, next) { console.log(res.locals); next();});
docsapp.addPreRender(defaultValues);
docsapp.addPreRender(includes.add);;
docsapp.addPreRender(overrideIfAuthenticated);
docsapp.addPreRender(overrideIfClientInQs);
docsapp.addPreRender(overrideIfClientInQsForPublicAllowedUrls);

5
docs/angular-tutorial.md Normal file
Просмотреть файл

@ -0,0 +1,5 @@
# Using Auth0 in Angular.js applications
Read the [Single Page Application tutorial](singlepageapp-tutorial) to get an idea of how Auth0 works in this scenario.
There is nothing in particular that needs to be done in Angular, other than instantiating the [widget](https://github.com/auth0/auth0-widget.js) or the [js wrapper]([widget](https://github.com/auth0/auth0.js)). Once the user has been authenticated, you can save the profile in a cookie/local storage/root scope. The `id_token` can be used to call your APIs and flow the user identity.

Просмотреть файл

@ -1,5 +1,7 @@
# Using Auth0 in ASP.NET Web API
@@includes.apinote@@
Install the following NuGet package
Install-Package WebApi.JsonWebToken
@ -22,3 +24,17 @@ Protect your Web API with the `[Authorize]` attribute
...
}
You can get the attributes of the user on the Web API side by doing:
ClaimsPrincipal.Current.Claims.SingleOrDefault(c => c.Type == "email").Value
## Consuming the secure API
* If you are building a Single Page / HTML5 Application, make sure to read [Using Auth0 in Single Page Apps / HTML5](singlepageapp-tutorial) to understand how to get a token on your application and send it to the Web API.
* If you are building a regular web site then you might want to read [Using Auth0 with ASP.NET](aspnet-tutorial).
* If you want to call this API from a console application or a powershell script, you could create a database connection to store credentials and obtain JSON Web Tokens based on those credentials as described in [Protocols - OAuth Resource Owner Password Credentials Grant](protocols#9).
* If you want to call this API from a WPF/Winforms app, read [Using Auth0 with WPF or Winforms](wpf-winforms-tutorial).
## Download the sample
Browse the sample on GitHub: <https://github.com/auth0/auth0-webapi-js-sample>

7
docs/ember-tutorial.md Normal file
Просмотреть файл

@ -0,0 +1,7 @@
# Using Auth0 in Ember.js applications
Read the [Single Page Application tutorial](singlepageapp-tutorial) to get an idea of how Auth0 works in this scenario.
There is nothing in particular that needs to be done in Ember, other than instantiating the [widget](https://github.com/auth0/auth0-widget.js) or the [js wrapper]([widget](https://github.com/auth0/auth0.js)). Once the user has been authenticated, you can save the profile in a cookie or local storage. The `id_token` can be used to call your APIs and flow the user identity.
Also, here is an [Ember.js example](https://github.com/kiwiupover/ember-auth0) for your reference. This example uses [auth0.js](https://github.com/auth0/auth0.js).

1
docs/includes/apinote.md Normal file
Просмотреть файл

@ -0,0 +1 @@
> <i class="fa fa-question-circle"></i> This tutorial explains how to add authentication to your API by relying a JSON Web Token which is signed with a secret. If you are building a regular web site (not a [single page or html5 app](singlepageapp-tutorial)) and the API is on the same domain, you don't need to implement this and we recommend you to follow the web apps tutorials and simply reuse the authentication cookie from the front end.

Просмотреть файл

@ -1,5 +1,7 @@
# Using Auth0 in Node.js APIs
@@includes.apinote@@
Install the following package which will provide an express middleware that validates a JSON Web Token.
npm install express-jwt

Просмотреть файл

@ -83,7 +83,7 @@ The last bit of code you will need are the handlers for the passport callbacks:
### 4. Setting up the callback URL in Auth0
<div class="setup-callback">
<p>After authenticating the user on Auth0, we will do a POST to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<p>After authenticating the user on Auth0, we will do a GET to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<pre><code>http://localhost:PORT/callback</pre></code>
</div>

Просмотреть файл

@ -7,7 +7,7 @@ The steps are quite simple though:
1. Setting up the callback URL in Auth0
<div class="setup-callback">
<p>After authenticating the user on Auth0, we will do a POST to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<p>After authenticating the user on Auth0, we will do a GET to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<pre><code>@@account.callback@@</pre></code>
</div>

Просмотреть файл

@ -1,5 +1,7 @@
# Using Auth0 in PHP APIs
@@includes.apinote@@
Install the following package from composer
firebase/php-jwt

Просмотреть файл

@ -1,5 +1,7 @@
# Using Auth0 in Ruby APIs
@@includes.apinote@@
Install the following gem
sudo gem install jwt

Просмотреть файл

@ -3,7 +3,7 @@
### 1. Setting up the callback URL in Auth0
<div class="setup-callback">
<p>After authenticating the user on Auth0, we will do a POST to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<p>After authenticating the user on Auth0, we will do a GET to a URL on your web site. For security purposes, you have to register this URL on the <strong>Application Settings</strong> section on Auth0 Admin app.</p>
<pre><code>http://localhost:PORT/callback</pre></code>
</div>
@ -14,12 +14,25 @@
### 3. Validate the JsonWebToken on the server
Auth0 returns a standard [JSON Web Token](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-12) in the browser location hash (http://yourapp#id_token=...). This token should be sent to the backend APIs to be validated.
Auth0 returns a standard [JSON Web Token](http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-12) in the browser location hash (http://yourapp#id_token=...). This token should be sent to the backend APIs to be validated in the `Authorization` header.
We have tutorials for several platforms and languages to get you up and running as quickly as possible:
This sample code sends the JSON Web Token on each call:
$.ajaxSetup({
'beforeSend': function(xhr) {
if ($.cookie('id_token')) {
xhr.setRequestHeader('Authorization',
'Bearer ' + $.cookie('id_token'));
}
}
});
To validate the token on the server side, we have tutorials for several platforms and languages to get you up and running as quickly as possible:
* [ASP.NET Web API](aspnetwebapi-tutorial)
* [Node.js API](nodeapi-tutorial)
* [Ruby API](rubyapi-tutorial)
* [PHP API](phpapi-tutorial)
> If your language/platform is missing you could Google for "JWT or JSON Web Token yourplatform". Or let us know: [mailto:support@auth0.com](support@auth0.com)

Просмотреть файл

@ -1,65 +1,12 @@
# Using Auth0 with ASP.NET Web API and Single Page Apps
# Using Auth0 in ASP.NET Web API
Integrating Auth0 with a Single Page Application (SPA) and a Web API backend is very simple and straightforward.
@@includes.apinote@@
##Before you start
1. You will need Visual Studio 2012 and MVC4
> You can also browse and download the [sample code on GitHub](https://github.com/auth0/auth0-webapi-js-sample)
##Integrating Auth0 with MVC4
###1. Create a simple MVC4 website
For this example, we will use the empty MVC4 Empty Template. Select __"FILE -> New project -> ASP.NET MVC 4 Web Application -> Empty"__
Once the default template unfolds, create a new Controller that derives from `ApiController`.
public class CustomersController : ApiController
{
// GET api/customers
public IEnumerable<string> Get()
{
return new string[] { "John Doe", "Nancy Davolo" };
}
}
You can also create a `HomeController` with an `Index` method and the `Index.cshtml` view that will be the shell for your JavaScript Single Page App.
> A regular HTML file would also work.
### 2. Setting up the callback URL in Auth0
<div class="setup-callback">
<p>After authenticating the user on Auth0, we will do a redirect to a URL on your web site. For security purposes, you have to register the callback URL of your website on the <strong>Application Settings</strong> section on Auth0 Admin app. For this type of application, the URL might look like this: </p>
<pre><code>http://localhost:some_random_port</pre></code>
</div>
### 3. Triggering login manually or integrating the Auth0 widget
@@sdk2WithCallbackOnHash@@
You can parse the information returned on the callback URL hash to get the `profile` (logged user information), `id_token`, `access_token` and `state` parameters:
widget.parseHash(window.location.hash, function (profile, id_token, access_token, state) {
// profile will be a JSON containing all the user properties (e.g.: profile.name)
// use id_token to call your rest api
});
> See the [User Profile](user-profile) document for details of the profile object returned.
###4. Securing the Web API
Auth0 will also give you a JSON Web Token which has been signed with your client secret. You should send this token in the `Authorizaton` header of your AJAX calls and validate it on the Web API. To accomplish this, we created a simple nuget package that will provide the JSON Web Token validation.
####Run the following command on the Nuget Package Manager Console:
Install the following NuGet package
Install-Package WebApi.JsonWebToken
####Add the following code snippet on the `Register` method of `WebApiConfig.cs`:
Add the following code snippet on the `Register` method of `WebApiConfig.cs`:
config.MessageHandlers.Add(new JsonWebTokenValidationHandler()
{
@ -67,9 +14,7 @@ Auth0 will also give you a JSON Web Token which has been signed with your client
SymmetricKey = "@@account.clientSecret@@" // client secret
});
> It would be advisable to put these properties in your all config (Web.config)
####Protect your Web API with the `[Authorize]` attribute
Protect your Web API with the `[Authorize]` attribute
public class CustomersController : ApiController
{
@ -79,44 +24,16 @@ Auth0 will also give you a JSON Web Token which has been signed with your client
...
}
###5. Calling the secured API
You can get the attributes of the user on the Web API side by doing:
The last step would be to call the API from your JavaScript application. To do so, you have to extract the `id_token` from the callback URL hash, and send it to your API as part of the Authorization header (e.g. `Authorization: Bearer ...id_token...`). Here is some code to do that:
ClaimsPrincipal.Current.Claims.SingleOrDefault(c => c.Type == "email").Value
widget.parseHash(window.location.hash, function (profile, id_token, access_token, state) {
$.ajax({
url: '/api/customers',
dataType: 'json',
beforeSend: function (request) {
if (id_token) request.setRequestHeader("Authorization", "Bearer " + id_token);
},
success: function (data, status, jqHXR) {
// data has API response
},
error: function (resp) {
if (resp.status == 401) {
// the token was invalid, not authorized
} else {
// server error
}
}
});
});
## Consuming the secure API
###6. Testing the app:
Open a browser, navigate to the website and press the login button. You should see Auth0 widget with a Google button, which is the default connection.
Once you are logged in, you can try calling the API with and without the Authorization header to make sure things are properly configured.
### Some extra tips...
You can get the user id on the Web API side by doing:
ClaimsPrincipal.Current.Claims.SingleOrDefault(c => c.Type == "sub").Value
You are done! Congratulations!
* If you are building a Single Page / HTML5 Application, make sure to read [Using Auth0 in Single Page Apps / HTML5](singlepageapp-tutorial) to understand how to get a token on your application and send it to the Web API.
* If you are building a regular web site then you might want to read [Using Auth0 with ASP.NET](aspnet-tutorial).
* If you want to call this API from a console application or a powershell script, you could create a database connection to store credentials and obtain JSON Web Tokens based on those credentials as described in [Protocols - OAuth Resource Owner Password Credentials Grant](protocols#9).
* If you want to call this API from a WPF/Winforms app, read [Using Auth0 with WPF or Winforms](wpf-winforms-tutorial).
## Download the sample

17
includes/includes.js Normal file
Просмотреть файл

@ -0,0 +1,17 @@
var path = require('path');
var fs = require('fs');
var includes = {};
module.exports.init = function(p) {
var files = fs.readdirSync(p);
files.forEach(function(file) {
var content = fs.readFileSync(path.join(p, file));
includes[path.basename(file, '.md')] = content;
});
}
module.exports.add = function(req, res, next) {
res.locals.includes = includes;
next();
}

Просмотреть файл

@ -3,16 +3,28 @@
</div>
<script src="<%= widget_url %>"></script>
<script>
<% if (callbackOnHash) { %> var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>',
callbackOnLocationHash: true
});<% } else { %> var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>'
});<% } %>
<% if (callbackOnHash) { %>
var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>',
callbackOnLocationHash: true
});<% } else { %>
var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>'
});<% } %>
<% if (callbackOnHash) { %>
// authentication result comes back in `window.location.hash`
widget.parseHash(window.location.hash, function (profile, id_token, access_token, state) {
/*
store the profile and id_token in a cookie or local storage
$.cookie('profile', profile);
$.cookie('id_token', id_token);
*/
});
<% } %>
widget.show({ container: 'root' });
widget.signin({ container: 'root' });
</script>

Просмотреть файл

@ -1,14 +1,26 @@
<script src="<%= widget_url %>"></script>
<script type="text/javascript">
<% if (callbackOnHash) { %> var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>',
callbackOnLocationHash: true
});<% } else { %> var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>'
});<% } %>
<% if (callbackOnHash) { %>
var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>',
callbackOnLocationHash: true
});<% } else { %>
var widget = new Auth0Widget({
domain: '<%= account.namespace %>',
clientID: '<%= account.clientId %>',
callbackURL: '<%= account.callback %>'
});<% } %>
<% if (callbackOnHash) { %>
// authentication result comes back in `window.location.hash`
widget.parseHash(window.location.hash, function (profile, id_token, access_token, state) {
/*
store the profile and id_token in a cookie or local storage
$.cookie('profile', profile);
$.cookie('id_token', id_token);
*/
});
<% } %>
</script>
<button onclick="widget.show()">Login</button>
<button onclick="widget.signin()">Login</button>

Просмотреть файл

@ -11,13 +11,12 @@
},
{
"title": "Web Apps",
"icon": "fa-desktop",
"icon": "fa-laptop",
"items": [
{ "title": "Node.js", "url": "/nodejs-tutorial" },
{ "title": "ASP.NET MVC", "url": "/aspnet-tutorial" },
{ "title": "Windows Azure", "url": "/azure-tutorial" },
{ "title": "ServiceStack", "url": "/servicestack-tutorial" },
{ "title": "WCF", "url": "/wcf-tutorial" },
{ "title": "Ruby on Rails", "url": "/rails-tutorial" }
]
},
@ -36,6 +35,7 @@
},
{
"title": "HTML5",
"icon": "fa-html5",
"items": [
{ "title": "Single Page Apps", "url": "/singlepageapp-tutorial" },
{ "title": "Ember.js", "url": "/ember-tutorial" },
@ -44,15 +44,18 @@
},
{
"title": "APIs",
"icon": "fa-terminal",
"items": [
{ "title": "ASP.NET Web API", "url": "/aspnetwebapi-tutorial" },
{ "title": "Node.js API", "url": "/nodeapi-tutorial" },
{ "title": "Ruby API", "url": "/rubyapi-tutorial" },
{ "title": "PHP API", "url": "/phpapi-tutorial" }
{ "title": "PHP API", "url": "/phpapi-tutorial" },
{ "title": ".NET WCF", "url": "/wcf-tutorial" }
]
},
{
"title": "Advanced topics",
"title": "Help Topics",
"icon": "fa-question-circle",
"items": [
{ "title": "Normalized Profile", "url":"/user-profile"},
{ "title": "Login Widget v2", "url":"/login-widget2"},

Просмотреть файл

@ -165,14 +165,14 @@ footer .right {
font-weight: bold;
color: #9CA5B5;
display: block;
margin: 20px 0 4px 0;
margin: 20px 0 4px 6px;
padding: 0 25px;
}
.container > nav > ul > li > span > i {
font-size: 20px;
font-size: 18px;
position: absolute;
margin-left: -16px;
margin-left: -22px;
}
.container > nav > ul ul {
@ -697,6 +697,7 @@ h4:hover a.anchor{
border: 1px solid #ccc;
border-radius: 5px;
background-color: rgba(255, 255, 255, 0.5);
padding: 5px;
}
.fixit i {

Просмотреть файл

@ -59,7 +59,7 @@ html(lang="en")
a(href=furl(l2.url))= l2.title
.fixit
| Found a typo?
i.icon-github-alt
i(class="fa fa-github")
a(href='#', target='_blank') Fix it :)
section
block content
@ -97,7 +97,7 @@ html(lang="en")
$('h2,h3,h4').each(function(){
$(this)
.attr('id', sectionIndex)
.prepend('<a class="anchor" href="#' + sectionIndex + '"><i class="icon-link"></i></a>');
.prepend('<a class="anchor" href="#' + sectionIndex + '"><i class="fa fa-link"></i></a>');
sectionIndex++;
});

Просмотреть файл

@ -57,6 +57,6 @@ html(lang="en")
$('h2,h3,h4').each(function(){
$(this)
.attr('id', sectionIndex)
.prepend('<a class="anchor" href="#' + sectionIndex + '"><i class="icon-link"></i></a>');
.prepend('<a class="anchor" href="#' + sectionIndex + '"><i class="fa fa-link"></i></a>');
sectionIndex++;
});