OAuth.io
Simplified multi-providers
authorization
OAuth
OAUTH 2 protocol
1 - Create the application
OAUTH 2 PROTOCOL
1 - Create the application
OAuth 2 Protocol
2 - Redirection
www.facebook.com/dialog/oauth/authorize
client_id=...
response_type=code
scope=email,read_friendlists...
redirect_uri=http://mysite.com
state=...
3 - Authorize callback
http://mysite.com/?code=...&state=...
4 - Receive the token
POST graph.facebook.com/oauth/access_token
code=...
client_id=...
client_secret=...
grant_type=authorization_code
OAuth 2 Protocol
2 - Redirection
client_id ->
app_id=...
response_type=code
scope -> perms=email,read_friendlists...
redirect_uri=http://mysite.com
state=... [non documenté]
3 - Authorize callback
http://mysite.com/?code=...&state=...
4 - Receive the token
code=...
client_id -> app_id=...
client_secret -> secret=...
grant_type=authorization_code
OAUTH 2 FLAWS
api.provider.com/path/action?access_token=TOKEN
api.provider.com/path/action?oauth_token=TOKEN
api.provider.com/path/action?token=TOKEN
Authorization: Bearer TOKEN
Authorization: OAuth TOKEN
OAUTH 2 flaws
scope=email%20publish
scope=email,publish
scope=email;publish
scope=email:publish
scope=email|publish
scope=read_only or scope=read_write
oauth 2 flaws
In the results of /access_token:
extra data (facultatif)
"user": {
id: "..."
name: "..."
// ...
}
extra data (requis)
"instance_url": "https://eu2.salesforce.com"
oauth 2 flaws
MailChimp
One added step: /oauth2/metadata
{
"dc":"us1",
"login_url":"https://login.mailchimp.com",
"api_endpoint":"https://us1.api.mailchimp.com"
}
oauth 2 flaws
Custom signature
mail.ru, odnoklassniki.ru, renren...
sig = md5(uid + params + private_key)
oauth 2 flaws
Custom constant
Tencent weibo:
oauth_version=2.a
OAUTH 2 FLAWS
The "state" param
- inexistent (dailymotion, eventbrite...)
- undocumented (wordpress, deezer...)
-
impossible (angellist)
Multi providers oauth
Oauth.io
OAUTH.IO
OAuth.popup('facebook', function(err, res) { if (err) { // do something with error }
// the access token is res.access_token !
})
OAUTH.io
OAuth.popup('facebook', function(err, res) { if (err) { // do something with error }
res.get('/me')
.done(function(data) { alert('Hello ' + data.name) }) })
OAUTH.IO
OAuth.popup('twitter', function(err, res) { if (err) { // do something with error }
res.get('/1.1/account/verify_credentials.json') .done(function(data) { alert('Hello ' + data.name) }) })
OAUTH.IO
Android, iOS, Flex et Phonegap
Examples
Client-side twitter timeline
TEMPLATE
<html ng-app="demoApp">
<head>
<!-- title, js/css (jquery/bootstrap/angular) -->
<script src="/oauth.js"></script> <script src="/app.js"></script> <link rel="stylesheet" type="text/css" href="/basic.css" /> </head> <body> <div class="container"> <h1>Twitter ~ client-side timeline</h1> <div class="well"> <div class="basic-content" ng-view></div> </div> </div> </body> </html>
Angularjs app
var demoApp = angular.module('demoApp', ['ngRoute']);
demoApp.config(function($routeProvider) {
$routeProvider.when('/timeline', {
templateUrl: '/partials/timeline.html',
controller: 'timelineCtrl'
}).when('/connect', {
templateUrl: '/partials/connect.html',
controller: 'connectCtrl'
}).otherwise({
redirectTo: '/connect'
});
});
CONNECT Controller
Connect Controller
<h3>Connect with twitter to see your home timeline</h3>
<button ng-click='connect()' class="btn btn-primary">
<img src="https://oauth.io/api/providers/twitter/logo" />
connect with twitter
</button>
demoApp.controller('connectCtrl', function ($scope,
$rootScope, $location) {
OAuth.initialize("hMOd7zAuUxDSM..."); $scope.connect = function() { OAuth.popup("twitter", function(err, res) { if (err) return alert(err); $rootScope.twitter = res; $location.path('/timeline'); $scope.$apply(); }); } });
TIMELINE CONTROLLER
TIMELINE CONTROLLER
<ul id="timeline" ng-repeat="entry in tw_timeline">
<li> <img class="thumb" src="{{entry.user.profile_image_url}}" /> <span class="content"> <span class="author">{{entry.user.name}}</span> <span class="text">{{entry.text}}</span> </span> </li> </ul>
demoApp.controller('timelineCtrl', function ($scope,
$rootScope) {
$rootScope.twitter.get('/1.1/statuses/home_timeline.json')
.done(function(data) { $scope.tw_timeline = data; $scope.$apply(); }); });
EXAMPLES
Synchro google drive
Connect ControlLER
... et redirige vers /editor
CONNECT CONTROLLER
$scope.connect = function() {
OAuth.popup("google_drive", function(err, res) {
if (err) return alert(err);
$rootScope.drive = res;
getDriveFile("realtime_test", function (file) {
$rootScope.drive_file = file;
$location.path('/editor');
$scope.$apply();
});
});
}
CONNECT CONTROLLER
getDriveFile
function getDriveFile(title, callback) {
$rootScope.drive.get({ url: "/drive/v2/files", data: {q: "title = '" + title + "'"} }).done(function(files) { if (files.items.length) return callback(files.items[0]); // create file if it does not exists createDriveFile(title, callback); }); }
connect controller
createDriveFile
function createDriveFile(title, callback) {
$rootScope.drive.post({ url: "/drive/v2/files", data: JSON.stringify({ title: title, mimeType:'application/vnd.google-apps.document'}), contentType: 'application/json' }).done(function(item) { callback(item); }); }
EDITOR Controller
EDITOR CONTROLLER
<textarea id="editor" ng-model="file_content"></textarea>
demoApp.controller('editorCtrl', function($scope,
$rootScope) {
$rootScope.drive.get(
$rootScope.drive_file.exportLinks['text/plain'])
.done(function(data) { $scope.file_content = data; $scope.$apply(); $scope.$watch("file_content", function() { $scope.must_save = true; updateFile();
});
}); function updateFile() { // ... } }
editor controller
updateFile
function updateFile() {
if ( ! $scope.must_save) return; if ($scope.saving) return setTimeout(updateFile, 50); $scope.saving = true; $scope.must_save = false; $rootScope.drive.put({ url: "/upload/drive/v2/files/" + $rootScope.drive_file.id + + "?uploadType=media", data: $scope.file_content }).always(function() { $scope.saving = false; updateFile(); }); }
Thanks !
Copy of OAuth.io + AngularJS [en-us]
By Thibaud Arnault
Copy of OAuth.io + AngularJS [en-us]
- 1,735