Have you ever shared your password with an app so it could use your data?
Yes :-(
1) Eliminate the need for users to reveal their password to apps
2) Restrict the level of data available to apps
3) Allow users to revoke access to their data
OAuth 2.0
for Authorization
Do you use the same username & password for multiple web sites?
Yes :-(
How many keystrokes do you type to sign up for a new account?
50+!
1) Minimize how many passwords users need
2) Optimize sign-up flows to onboard users faster
OpenID Connect
RFC 6749 is a:
Framework
100+ APIs
Goal
gapi.auth.authorize({ client_id: '387636757294.apps.googleusercontent.com', scope: 'https://www.googleapis.com/auth/tasks'}, handleAuthResultPopup); function handleAuthResultPopup() { alert(gapi.auth.getToken()); }
<script type="text/javascript"> var clientId = '387636757294.apps.googleusercontent.com'; var authorizationUrlBase = 'https://accounts.google.com/o/oauth2/auth'; var redirectUri = 'https://taskmandemo.appspot.com/oauth2callback.html'; var scope = 'https://www.googleapis.com/auth/tasks'; function startOauth() { var url = authorizationUrlBase; url += '?response_type=token' + '&redirect_uri=' + encodeURIComponent(redirectUri) + '&client_id=' + encodeURIComponent(clientId) + '&scope=' + encodeURIComponent(scope); var w = window.open(url, 'oauth', 'width=500,height=400'); } </script>
https://accounts.google.com/o/oauth2/auth? client_id=387636757294.apps.googleusercontent.com& scope=https://www.googleapis.com/auth/tasks& redirect_uri=https://taskmandemo.appspot.com/oauth2callback.html& response_type=token
https://taskmandemo.appspot.com/oauth2callback.html# access_token=ya29.AHES6ZT8XLGWjlrYfP1KvkLQVvYj81C6uA_bUsaZBKWB4ZE& token_type=Bearer& expires_in=3600
flow = OAuth2WebServerFlow( # Visit https://developers.google.com/console to # generate your client_id, client_secret and to # register your redirect_uri. client_id='387636757294.apps.googleusercontent.com', client_secret='-8IwOyyundwNY6W0B', scope='https://www.googleapis.com/auth/tasks') callback = self.request.relative_url('/oauth2callback') authorize_url = flow.step1_get_authorize_url(callback) self.redirect(authorize_url)
https://accounts.google.com/o/oauth2/auth? client_id=387636757294.apps.googleusercontent.com& scope=https://www.googleapis.com/auth/tasks& redirect_uri=https://taskmandemo.appspot.com/oauth2callback& response_type=code& access_type=offline
https://taskmandemo.appspot.com/oauth2callback? code=4/jHpY6Rslb32PWBiR9bU6wJ4GrMmF.EjOUBPzd
credentials = flow.step2_exchange(self.request.params) print 'Access token: %s' % credentials.access_token
print 'Refresh token: %s' % credentials.refresh_token
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com client_id=387636757294.apps.googleusercontent.com& redirect_uri=https://taskmandemo.appspot.com/oauth2callback& grant_type=authorization_code& code=4/jHpY6Rslb32PWBiR9bU6wJ4GrMmF.EjOUBPzd& client_secret=-8IwOyyundwNY6W0B
{ "access_token":"1/fFAGRNJru1FTz70BzhT3Zg", "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" "expires_in":3600, "token_type":"Bearer", }
# nothing to see here!
POST /o/oauth2/token HTTP/1.1 Host: accounts.google.com Content-Type: application/x-www-form-urlencoded client_id=387636757294.apps.googleusercontent.com& client_secret=-8IwOyyundwNY6W0B& refresh_token=1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI& grant_type=refresh_token
{ "access_token":"1/hGAFZKUio3NOc90BxjU48l", "expires_in":3600, "token_type":"Bearer" }
decorator = OAuth2Decorator( client_id='387636757294.apps.googleusercontent.com' client_secret='-8IwOyyundwNY6W0B' scope='https://www.googleapis.com/auth/tasks') http = httplib2.Http(memcache) service = build("tasks", "v1", http=http) class MainHandler(webapp.RequestHandler): @decorator.oauth_required def get(self): http = decorator.http() tasks = service.tasks.list(tasklist='@default').execute(http)
GET /tasks/v1/lists/@default/tasks HTTP/1.1 Host: www.googleapis.com Authorization: Bearer 1/hGAFZKUio3NOc90BxjU48l
GET /tasks/v1/lists/@default/tasks?access_token=1/hGAFZKUio3NOc90BxjU48l HTTP/1.1 Host: www.googleapis.com
https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/plus.me
// Allow user to select an account // AccountManager.getAccountsByType("com.google"); String scope = "https://www.googleapis.com/auth/tasks"; // Get an access token for 'email' account and requested scope String token = GoogleAuthUtil.getToken(context, email, scope);
First name:
Last name:
Email:
Profile:
Scope | Description |
---|---|
https://www.googleapis.com/auth/userinfo.profile | Unique id, name, profile photo, profile URL, country, language, timezone, birthdate, etc. |
https://www.googleapis.com/auth/userinfo.email | E-mail address |
https://accounts.google.com/o/oauth2/auth? client_id=387636757294.apps.googleusercontent.com& scope=https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email& redirect_uri=https://taskmandemo.appspot.com/oauth2callback-authn.html& response_type=token
https://www.googleapis.com/oauth2/v1/tokeninfo? access_token=
{ "issued_to": "387636757294.apps.googleusercontent.com", "audience": "387636757294.apps.googleusercontent.com", "user_id": "113487456102835830811", "scope": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", "expires_in": 3574, "email": "ryan@ryguy.com", "verified_email": true, "access_type": "online" }
https://www.googleapis.com/oauth2/v1/userinfo? access_token=
{ "id": "113487456102835830811", "email": "ryan@ryguy.com", "verified_email": true, "name": "Ryan Boyd", "given_name": "Ryan", "family_name": "Boyd", "link": "https://plus.google.com/113487456102835830811", "picture": "https://lh4.googleusercontent.com/-BET-bMzn99g/AAAAAAAAAAI/AAAAAAAAAQ8/wV0kQ3VUjOE/photo.jpg", "gender": "male", "birthday": "0000-10-05", "locale": "en" }
<script src="http://plus.google.com/js/plusone.js"></script> <div id="signinButton"> <span class="g-signin" data-scope="https://www.googleapis.com/auth/plus.login" data-clientid="387636757294.apps.googleusercontent.com" data-redirecturi="postmessage" data-accesstype="offline" data-cookiepolicy="single_host_origin" data-callback="handleAuthResult"> </span> </div> <div id="result"></div>
function handleAuthResult(authResult) { alert(authResult['access_token']); }