CARVIEW |
Select Language
HTTP/2 200
date: Wed, 23 Jul 2025 10:01:56 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
etag: W/"5772bcdb7b47171acc2a4af5ae7fa41a"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: origin-when-cross-origin, strict-origin-when-cross-origin
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=V5GuIfiitpaKA5z7RvIxB7BnFzxI7oL764ZendFBIgaiY%2BT4AZ4y%2BLV32aZVr5HSc%2BR1QXMaBYb6jByyY6YckGHVcc110G6LOCpH6w39q8566r1XzXtK3DVAZ7CqWswBwmM%2FL9fMZlwofUuYR3mbni6HTs6ThpXgKTAyaEq7hLcKCqJxaNpmtYJKWWJoYhofVd6nzQxciedRCZNc59AhqvlM3L6VUs2sutLDmXsma%2FjGID0a%2FS7VeasW22TlOxVEwodVuvyL2DzlGHd065yQGQ%3D%3D--MhbQeY5TKkMjDOUc--p1NxJn3QwFuTCm8Qtr%2B%2Frg%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.1730552614.1753264916; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 10:01:56 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Thu, 23 Jul 2026 10:01:56 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 8BDE:26221E:8C4047:AAB4F2:6880B314
Reddit OAuth2 Java sample code (uses Google HTTP and json.org libs) · GitHub
Show Gist options
Save GitTom/10493132 to your computer and use it in GitHub Desktop.
{{ message }}
Instantly share code, notes, and snippets.
Last active
June 30, 2019 15:42
-
Star
10
(10)
You must be signed in to star a gist -
Fork
3
(3)
You must be signed in to fork a gist
-
Save GitTom/10493132 to your computer and use it in GitHub Desktop.
Reddit OAuth2 Java sample code (uses Google HTTP and json.org libs)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.util.HashMap; | |
import java.util.Map; | |
import org.json.JSONObject; | |
import org.json.JSONTokener; | |
import com.google.api.client.extensions.appengine.http.UrlFetchTransport; | |
import com.google.api.client.http.GenericUrl; | |
import com.google.api.client.http.HttpContent; | |
import com.google.api.client.http.HttpRequest; | |
import com.google.api.client.http.HttpRequestFactory; | |
import com.google.api.client.http.HttpRequestInitializer; | |
import com.google.api.client.http.HttpResponse; | |
import com.google.api.client.http.HttpTransport; | |
import com.google.api.client.http.UrlEncodedContent; | |
import com.google.appengine.api.utils.SystemProperty; | |
// Reddit's OAUTH docs are here: | |
// https://github.com/reddit/reddit/wiki/OAuth2 | |
// https://www.reddit.com/r/redditdev/comments/218wd7/oauth_20_you_asked_i_listened_updated_and_more/ | |
// Docs for Google HTTP lib, and GAE urlfetch: | |
// https://code.google.com/p/google-http-java-client/ | |
// https://developers.google.com/appengine/docs/java/urlfetch/ | |
// Apache License | |
// copyright 2014 /u/redlist-admin | |
// You will need to comment out or replace my custom Log statements. | |
public class RedditOAuth { | |
// This line is GAE specific! for detecting when running on local admin | |
public static final boolean production = (SystemProperty.Environment.Value.Production == SystemProperty.environment.value()); | |
public static final String OAUTH_API_DOMAIN = "https://oauth.reddit.com"; | |
// Step 1. Send user to auth URL | |
public static final String OAUTH_AUTH_URL = "https://ssl.reddit.com/api/v1/authorize"; | |
// https://ssl.reddit.com/api/v1/authorize?client_id=CLIENT_ID&response_type=TYPE&state=RANDOM_STRING&redirect_uri=URI&duration=DURATION&scope=SCOPE_STRING | |
// Step 2. Reddit sends user to REDIRECT_URI | |
private static final String REDIRECT_URI = production ? <your app domain> + "/auth" | |
: "https://127.0.0.1:8888/auth"; | |
// Step 3. Get token | |
public static final String OAUTH_TOKEN_URL = "https://ssl.reddit.com/api/v1/access_token"; | |
// I think it is easier to create 2 reddit apps (one with 127.0.0.1 redirect URI) | |
public static final String MY_APP_ID = production ? "???????????" : "???????"; | |
public static final String MY_APP_SECRET = production ? "??????????" : "???????"; | |
public static final String SCOPE_ID = "identity"; | |
// Field name in responses | |
public static final String ACCESS_TOKEN_NAME = "access_token"; | |
public static final String REFRESH_TOKEN_NAME = "refresh_token"; | |
public static boolean permanentAccess = true; | |
public static String getUserAuthUrl(String state) { | |
String duration = permanentAccess ? "permanent" : "temporary"; | |
String url = OAUTH_AUTH_URL + "?client_id=" + MY_APP_ID + "&response_type=code&state=" + state | |
+ "&redirect_uri=" + REDIRECT_URI + "&duration=" + duration + "&scope=" + SCOPES; | |
// scopes: modposts, identity, edit, flair, history, modconfig, modflair, modlog, modposts, modwiki, | |
// mysubreddits, privatemessages, read, report, save, submit, subscribe, vote, wikiedit, wikiread, etc. | |
return url; | |
} | |
// The Google Java HTTP library has a 'pluggable' architecture - the following line selects the URLFetch transport, | |
// which is the native HTTP api for GAE. 'NetHttpTransport()' would be a more generic alternative. | |
public static final HttpTransport HTTP_TRANSPORT = new UrlFetchTransport(); | |
// public static final JsonFactory JSON_FACTORY = new JacksonFactory(); | |
public static JSONObject getToken(String code) throws IOException { | |
Log.v( "getToken for code=" + code ); | |
GenericUrl url = new GenericUrl(OAUTH_TOKEN_URL); | |
Map<String, String> params = new HashMap<String, String>(3); | |
params.put("grant_type", "authorization_code"); | |
params.put("code", code); | |
params.put("redirect_uri", REDIRECT_URI); | |
HttpContent hc = new UrlEncodedContent(params); | |
HttpRequestFactory requestFactory = HTTP_TRANSPORT | |
.createRequestFactory(new HttpRequestInitializer() { | |
@Override | |
public void initialize(HttpRequest request) { | |
// request.setParser( new JsonObjectParser(JSON_FACTORY) ); | |
request.getHeaders().setBasicAuthentication(MY_APP_ID, MY_APP_SECRET); | |
} | |
}); | |
HttpRequest request = requestFactory.buildPostRequest(url, hc); | |
HttpResponse response = request.execute(); | |
JSONObject jo = null; | |
try { | |
if (response.isSuccessStatusCode()) { | |
String json = response.parseAsString(); | |
Log.i("Success with " + json); | |
// Parse with org.json | |
JSONTokener tokener = null; | |
tokener = new JSONTokener( json ); | |
jo = new JSONObject(tokener); | |
// Sample response: | |
// {"access_token": "cdkVPfKww5R0D1v-MJAD89Y19QM", | |
// "token_type": "bearer", | |
// "expires_in": 3600, | |
// "refresh_token": "vzZ0PP0A4k-twzSuVyvRN7uH2JY", | |
// "scope": "identity"} | |
} else | |
Log.w("Request failed with " + response.getStatusCode()); | |
} finally { | |
response.disconnect(); | |
} | |
return jo; | |
} | |
public static JSONObject refreshToken(String reftoke) throws IOException { | |
Log.v( "refreshToken with reftoke=" + reftoke ); | |
GenericUrl url = new GenericUrl(OAUTH_TOKEN_URL); | |
Map<String, String> params = new HashMap<String, String>(3); | |
params.put("grant_type", "refresh_token"); | |
params.put("refresh_token", reftoke); | |
HttpContent hc = new UrlEncodedContent(params); | |
HttpRequestFactory requestFactory = HTTP_TRANSPORT | |
.createRequestFactory(new HttpRequestInitializer() { | |
@Override | |
public void initialize(HttpRequest request) { | |
request.getHeaders().setBasicAuthentication(MY_APP_ID, MY_APP_SECRET); | |
} | |
}); | |
HttpRequest request = requestFactory.buildPostRequest(url, hc); | |
HttpResponse response = request.execute(); | |
JSONObject jo = null; | |
try { | |
if (response.isSuccessStatusCode()) { | |
String json = response.parseAsString(); | |
Log.i("Success with " + json); | |
JSONTokener tokener = null; | |
tokener = new JSONTokener( json ); | |
jo = new JSONObject(tokener); | |
// Sample response: | |
// { "access_token": Your access token, | |
// "token_type": "bearer", | |
// "expires_in": Unix Epoch Seconds, | |
// "scope": A scope string, } | |
} else | |
Log.w("Request failed with " + response.getStatusCode()); | |
} finally { | |
response.disconnect(); | |
} | |
return jo; | |
} | |
// https://www.reddit.com/dev/api | |
// https://oauth.reddit.com/api/v1/me | |
public static final String ENDPOINT_ID = OAUTH_API_DOMAIN + "/api/v1/me"; | |
public static final String ENDPOINT_SUBS = OAUTH_API_DOMAIN + "/subreddits/mine/"; // a list endpoint | |
// Followed by 'subscriber', 'contributor', or 'moderator' | |
public static JSONObject getInfo( final String token ) throws IOException { | |
Log.v( "getInfo with token=" + token ); | |
GenericUrl url = new GenericUrl( ENDPOINT_ID ); | |
HttpRequestFactory requestFactory = HTTP_TRANSPORT | |
.createRequestFactory(new HttpRequestInitializer() { | |
@Override | |
public void initialize(HttpRequest request) { | |
request.getHeaders().setAuthorization( "bearer " + token ); | |
} | |
}); | |
HttpRequest request = requestFactory.buildGetRequest( url ); | |
HttpResponse response = request.execute(); | |
JSONObject jo = null; | |
try { | |
if (response.isSuccessStatusCode()) { | |
String json = response.parseAsString(); | |
//Log.i("Success with " + json); | |
// Sample response: | |
// {"name": "myName", "created": 1346020929.0, "created_utc": 1346017329.0, "link_karma": 1308, | |
// "comment_karma": 32602, "over_18": true, "is_gold": true, "is_mod": false, "has_verified_email": true, "id": "76gyp"} | |
// Parse with org.json | |
JSONTokener tokener = null; | |
tokener = new JSONTokener( json ); | |
jo = new JSONObject(tokener); | |
} else | |
Log.w("Request failed with " + response.getStatusCode()); | |
} finally { | |
response.disconnect(); | |
} | |
return jo; | |
} | |
// A generic get fn to build the rest of my API calls around | |
public static JSONObject get( final String surl, final String token ) throws IOException { | |
Log.v( "get for URL=" + surl ); | |
GenericUrl url = new GenericUrl( surl ); | |
HttpRequestFactory requestFactory = HTTP_TRANSPORT | |
.createRequestFactory(new HttpRequestInitializer() { | |
@Override | |
public void initialize(HttpRequest request) { | |
// request.setParser( new JsonObjectParser(JSON_FACTORY) ); | |
request.getHeaders().setAuthorization( "bearer " + token ); | |
} | |
}); | |
HttpRequest request = requestFactory.buildGetRequest( url ); | |
HttpResponse response = request.execute(); | |
JSONObject jo = null; | |
// Note the recommended use of finally { disconnect() } | |
try { | |
if (response.isSuccessStatusCode()) { | |
String json = response.parseAsString(); | |
Log.i("Success with " + json); | |
// Parse with org.json | |
JSONTokener tokener = null; | |
tokener = new JSONTokener( json ); | |
jo = new JSONObject(tokener); | |
// Or Parse directly into Java objects using Jackson | |
} else | |
Log.w("Request failed with " + response.getStatusCode()); | |
} finally { | |
response.disconnect(); | |
} | |
return jo; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can’t perform that action at this time.
This code was tested on GAE/J SDK 1.9.0. It is suitable for use on most platforms, including Android, but note that this form of OAuth is the server form - you will need to adjust for client side applications.