{"action":"closed","issue":{"url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/2589","labels_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/2589/labels{/name}","comments_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/2589/comments","events_url":"https://api.github.com/repos/mozilla/fxa-content-server/issues/2589/events","html_url":"https://github.com/mozilla/fxa-content-server/issues/2589","id":87625979,"number":2589,"title":"Add support for \"access_type\" oauth parameter, for requesting refresh tokens","user":{"login":"rfk","id":34695,"avatar_url":"https://avatars.githubusercontent.com/u/34695?v=3","gravatar_id":"","url":"https://api.github.com/users/rfk","html_url":"https://github.com/rfk","followers_url":"https://api.github.com/users/rfk/followers","following_url":"https://api.github.com/users/rfk/following{/other_user}","gists_url":"https://api.github.com/users/rfk/gists{/gist_id}","starred_url":"https://api.github.com/users/rfk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rfk/subscriptions","organizations_url":"https://api.github.com/users/rfk/orgs","repos_url":"https://api.github.com/users/rfk/repos","events_url":"https://api.github.com/users/rfk/events{/privacy}","received_events_url":"https://api.github.com/users/rfk/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":{"login":"seanmonstar","id":51479,"avatar_url":"https://avatars.githubusercontent.com/u/51479?v=3","gravatar_id":"","url":"https://api.github.com/users/seanmonstar","html_url":"https://github.com/seanmonstar","followers_url":"https://api.github.com/users/seanmonstar/followers","following_url":"https://api.github.com/users/seanmonstar/following{/other_user}","gists_url":"https://api.github.com/users/seanmonstar/gists{/gist_id}","starred_url":"https://api.github.com/users/seanmonstar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seanmonstar/subscriptions","organizations_url":"https://api.github.com/users/seanmonstar/orgs","repos_url":"https://api.github.com/users/seanmonstar/repos","events_url":"https://api.github.com/users/seanmonstar/events{/privacy}","received_events_url":"https://api.github.com/users/seanmonstar/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/mozilla/fxa-content-server/milestones/52","html_url":"https://github.com/mozilla/fxa-content-server/milestones/train%2041","labels_url":"https://api.github.com/repos/mozilla/fxa-content-server/milestones/52/labels","id":1110389,"number":52,"title":"train 41","description":"Train 41 - June 23-July 6","creator":{"login":"shane-tomlinson","id":848085,"avatar_url":"https://avatars.githubusercontent.com/u/848085?v=3","gravatar_id":"","url":"https://api.github.com/users/shane-tomlinson","html_url":"https://github.com/shane-tomlinson","followers_url":"https://api.github.com/users/shane-tomlinson/followers","following_url":"https://api.github.com/users/shane-tomlinson/following{/other_user}","gists_url":"https://api.github.com/users/shane-tomlinson/gists{/gist_id}","starred_url":"https://api.github.com/users/shane-tomlinson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shane-tomlinson/subscriptions","organizations_url":"https://api.github.com/users/shane-tomlinson/orgs","repos_url":"https://api.github.com/users/shane-tomlinson/repos","events_url":"https://api.github.com/users/shane-tomlinson/events{/privacy}","received_events_url":"https://api.github.com/users/shane-tomlinson/received_events","type":"User","site_admin":false},"open_issues":17,"closed_issues":2,"state":"open","created_at":"2015-05-14T15:17:26Z","updated_at":"2015-07-02T17:26:57Z","due_on":"2015-07-05T23:00:00Z","closed_at":null},"comments":8,"created_at":"2015-06-12T06:27:42Z","updated_at":"2015-07-02T17:26:57Z","closed_at":"2015-07-02T17:26:57Z","body":"In https://github.com/mozilla/fxa-oauth-server/pull/260 we're moving towards a \"refresh token\" model for oauth tokens.  In this new world, access tokens will expire after some short timeframe.  For reliers that require ongoing access to profile information, they can request a special \"refresh token\" that will allow them to mint new access tokens at will.\r\n\r\nFor context, the overall flow is quite similr to the way that Google does it [1] and goes like this:\r\n\r\n* The relier requests `GET /authorization?client_id=blahblah&access_type=offline` to indicate they want a refresh token.\r\n* The oauth-server redirects to the content server to begin the oauth dance.\r\n* The content-server processes the authorization and does `POST /authorization { assertion: blahblah, access_type: \"offline\" }` to complete the dance, then redirects back to the relier.\r\n* The relier takes the code from the redirect, posts it to the oauth-server like `POST /token { code: \"XYZ\" }` and gets back a refresh_token along with the usual access_token:  `{ access_token: \"ABCDEF\", refresh_token: \"UVWXYZ\" }`.\r\n* The access_token can be used straight away to access oauth-protected resources, just like it can now.  But it will expire after a short while (currently on the order of weeks, but we may shrink that).\r\n* When the access_token expires, the relier can use the refresh_token to request a fresh access_token by doing `POST /token { refresh_token: \"UVWXYZ\" }`, without involving the user again.\r\n\r\nThe content-server's responsibilities in this dance will be:\r\n\r\n* Accept `access_type=[online|offline]` when beginning the oauth dance, and remember that state.\r\n* Somehow indicate to the user that they're giving the relier ongoing access to their data.\r\n* Echo back the `access_type` parameter when creating the oauth code at the end of the dance.\r\n\r\n/cc @seanmonstar\r\n\r\n[1] https://developers.google.com/identity/protocols/OAuth2WebServer#offline"}}