RedDit oAuth 2 para Android aplicación "sin usuario" con Retrofit
Estoy tratando de implementar el RedDit oAuth2 (cada aplicación que utiliza el contenido de Reddit tiene que tener esta implementada ) en la aplicación basada en Android "sin usuarios" y estoy siguiendo las directrices.
- He registrado una aplicación y obtengo el respectivo
client_id
. - Estoy siguiendo esto para las directrices de la API y esto para Retrofit para escribir correctamente el código de Android.
Por lo tanto, he codificado dos enfoques de la cuestión y parece que no funciona. La llamada en el Fragmento apropiado es la misma para las dos opciones y va como sigue:
- Cómo obtener malformado JSON en Retrofit 2
- Renovación de la referencia $ ref de objeto deserializante de JSON a su copia original
- ¿Cómo estructurar mi aplicación usando MVP con rxjava y retrofit para obtener datos de Observables?
- RxJava onCompleted y onTerminate en el hilo principal
- Cómo crear NTLM Authentification con Retrofit
public void oAuth(){ String bodyString = "grant_type=" + "https://oauth.reddit.com/grants/installed_client" + "&device_id=" + UUID.randomUUID().toString(); TypedInput requestBody = new TypedByteArray("application/x-www-form-urlencoded", bodyString.getBytes(Charset.forName("UTF-8"))); RedditAPI.sRedditAuth().redditAuth(requestBody, new Callback<TokenResponse>() { @Override public void success(TokenResponse tokenResponse, Response response) { Log.d("OATH_TAG", "oAuth() | YAY! :)"); } @Override public void failure(RetrofitError error) { Log.d("OATH_TAG", "oAuth() | NOOOOOoooooo.... :("); } }); }
OPCIÓN 1:
-
La interfaz de Retrofit:
public interface RedditAuthInterface { @POST(Urlz.REDDIT_OATH2_PATH) void redditAuth(@Body TypedInput body, Callback<TokenResponse> result); } //the adapter public static RedditAuthInterface sRedditAuth() { if (sRedditAuthInterface == null) { RestAdapter restAdapter = new RestAdapter .Builder() .setClient(getAuthClient()) .setEndpoint(Urlz.BASE_REDDIT_URL) .build(); sRedditAuthInterface = restAdapter.create(RedditAuthInterface.class); } return sRedditAuthInterface; } /* support methods */ private static OkClient getAuthClient() { final OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setReadTimeout(Static.READ_TIMEOUT, TimeUnit.SECONDS); okHttpClient.setConnectTimeout(Static.CONNECT_TIMEOUT, TimeUnit.SECONDS); /*okHttpClient.setAuthenticator(new Authenticator() { @Override public Request authenticate(Proxy proxy, Response response) throws IOException { String credential = Credentials.basic(BldCnfg.REDDIT_CLIENT_ID, BldCnfg.REDDIT_PASS); return response.request().newBuilder().header("Authorization", credential).build(); } @Override public Request authenticateProxy(Proxy proxy, Response response) throws IOException { return null; } });*/ okHttpClient.networkInterceptors().add(OAUTH_INTERCEPTOR); return new OkClient(okHttpClient); } private static final Interceptor OAUTH_INTERCEPTOR = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response originalResponse = chain.proceed(chain.request()); String credentials = BldCnfg.REDDIT_CLIENT_ID + ":" + BldCnfg.REDDIT_PASS; // REDDIT_PASS = "" as by API guides String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); originalResponse.header("Authorization", string); originalResponse.header("Accept", "application/json"); return originalResponse; } };
-
resultado:
RetrofitError: 401 no autorizado
OPCION 2:
-
La interfaz de Retrofit:
public interface RedditAuthInterface { @POST(Urlz.REDDIT_OATH2_PATH) void redditAuth(@Body TypedInput body, Callback<TokenResponse> result); } //the adapter public static RedditAuthInterface sRedditAuth() { if (sRedditAuthInterface == null) { RestAdapter restAdapter = new RestAdapter .Builder() .setClient(getConfuguredClient()) .setRequestInterceptor(getRequestInerceptorPass()) .setEndpoint(Urlz.BASE_REDDIT_URL) .build(); sRedditAuthInterface = restAdapter.create(RedditAuthInterface.class); } return sRedditAuthInterface; } /* support methods */ public static RequestInterceptor getRequestInerceptorPass() { RequestInterceptor rqInter = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { String credentials = BldCnfg.REDDIT_CLIENT_ID + ":" + BldCnfg.REDDIT_PASS; // REDDIT_PASS = "" as by API guides String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); request.addHeader("Authorization", string); request.addHeader("Accept", "application/json"); } }; return rqInter; } private static OkClient getConfuguredClient() { final OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setReadTimeout(Static.READ_TIMEOUT, TimeUnit.SECONDS); okHttpClient.setConnectTimeout(Static.CONNECT_TIMEOUT, TimeUnit.SECONDS); return new OkClient(okHttpClient); }
-
resultado:
Parece que estoy recibiendo una respuesta vacía (solo obtengo "*" por alcance). La respuesta correcta tiene este aspecto:
Y encabezado como este:
¿Tienes alguna idea de lo que estoy haciendo mal? ¿Alguien ha hecho esto?
El wiki oficial de Reddit github carece de ejemplos de Android (en casi todos los demás idiomas, sin embargo).
- No vuelva a ejecutar la llamada de Retrofit si todavía está en curso con RxJava 2
- Android aar dependencias
- Subir varias imágenes al servidor en una cola
- Manera correcta de manejar ninguna red con Retrofit y RX-java
- ¿Cuándo se debe usar RxJava Observable y cuándo Callback simple en Android?
- Retrofit y GET utilizando parámetros
- Deserialización GSON de una lista envuelta de objetos
- Encadenamiento de llamadas de Retrofit con RxJava y devolución del objeto principal
Yo estaba pasando por el mismo problema antes y hacer esta biblioteca para handel OAuth2 en Android. Y la biblioteca es una extensión para Retrofit que simplifica el proceso de autenticación contra un proveedor OAuth 2.
Sobre la base de su imagen con la respuesta "vacía", mostrando que tiene *
volver como un ámbito, sospecho que su definición de la respuesta de token de acceso está usando la caja de camello en lugar de la caja de serpiente, por lo que el JSON no se carga correctamente en la Objeto Java.