Skip to content
Matthew Dean edited this page Feb 22, 2015 · 10 revisions

###Types of Authentication

There are five types of authentication available under Reddit's OAuth implementation: Script, application-only, application-only installed app, installed app, and web.

  • Web app: Runs as part of a web service on a server you control. Can keep a secret.
  • Installed app: Runs on devices you don't control, such as the user's mobile phone. Cannot keep a secret, and therefore, does not receive one.
  • Script app: Runs on hardware you control, such as your own laptop or server. Can keep a secret. Only has access to your account.
  • Application-only: A web or script app acting in a user-less context.
  • Application-only installed app: The summation of "installed app" and "application-only."

###Script and Application-Only

These types are the easiest to authenticate. Invoking OAuthHelper.easyAuth(Credentials) will result in a OAuthData instance, given the credentials are valid. An example:

RedditClient redditClient = new RedditClient(...);
// This could also be Credentials.userless() or .userlessApp()
Credentials credentials = Credentials.script(...);
OAuthData authData = redditClient.getOAuthHelper().easyAuth(credentials);
redditClient.authenticate(authData);

###Web and Installed Apps

Web and installed apps are harder to authenticate because they require the user to allow the app's permissions (scopes) action using a browser. A rough outline of this process goes as follows:

  1. Obtain an authorization URL using getAuthorizationUrl(Credentials, boolean, String...).
  2. Point the user's browser to that URL and have the user login and then press 'accept' on the authentication form. The URL that the browser redirects to will be your app's redirect URI with some arguments in the query.
  3. Provide this data as well as the same Credentials instance to OAuthHelper.onUserChallenge(String, Credentials). This method will parse the query arguments and report any errors. Once the response's integrity has been verified, a request to obtain the OAuth access code will be made and an instance of OAuthData retrieved.

A minimal example for Android:

public class MainActivity extends Activity {
    private static final String REDIRECT_URL = ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create our RedditClient
        RedditClient reddit = new RedditClient(UserAgent.of(...));
        final OAuthHelper helper = reddit.getOAuthHelper();
        // This is Android, so our OAuth app should be an installed app.
        final Credentials credentials = Credentials.installedApp(...);

        // If this is true, then you will be able to refresh to access token
        boolean permanent = true;
        // OAuth2 scopes to request. See https://www.reddit.com/dev/api/oauth for a full list
        String[] scopes = {"identity", "read"};

        URL authorizationUrl = helper.getAuthorizationUrl(credentials, permanent, scopes);
        // Load the authorization URL into the browser
        webView.loadUrl(authorizationUrl.toExternalForm());
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                if (url.contains("code=")) {
                    // We've detected the redirect URL
                    new UserChallengeTask(helper, credentials).execute(url);
                }
            }
        });
    }

    private static final class UserChallengeTask extends AsyncTask<String, Void, OAuthData> {
        private OAuthHelper helper;
        private Credentials creds;
        public UserChallengeTask(OAuthHelper helper, Credentials creds) {
            // <assign fields to parameters>
        }

        @Override
        protected OAuthData doInBackground(String... params) {
            try {
                return helper.onUserChallenge(params[0], REDIRECT_URL, creds);
            } catch (NetworkException | OAuthException e) {
                // Handle me gracefully
            }
        }

        @Override
        protected void onPostExecute(OAuthData oAuthData) {
            reddit.authenticate(oAuthData);
        }
    }
}

###Refreshing Access Tokens

To refresh an access token, the permission must have been requested during getAuthorizationUrl(Credentials, boolean, String...), where permanent = true. Note that this disqualifies script and application-only apps. A new access token may be requested using OAuthHelper.refreshToken(Credentials). For example:

// Provided that 'redditClient' is an already-authenticated RedditClient
// and `credentials' is a Credentials object for a web/installed app:
OAuthData newAuthData = redditClient.getOAuthHelper().refreshToken(credentials);
redditClient.authenticate(newAuthData);

###Revoking Access Tokens

Good clients clean up after themselves. That's why OAuthHelper.revokeToken(Credentials) is provided. Simply call this method when your app no longer needs to hold on to the access token and it will be invalidated.

Clone this wiki locally