2015-07-28 28 views
5

Sto cercando di implementare Reddit oAuth2 (ogni app che utilizza il contenuto Reddit deve avere questo implemented) in un'applicazione "userless" basata su Android e sto seguendo le linee guida .Reddit oAuth 2 per Android app "userless" con Retrofit

  1. I registered an app e ottenere il rispettivo client_id.
  2. Sto seguendo questo per API guidelines e this for Retrofit per scrivere correttamente il codice Android.

Quindi, ho codificato due approcci al problema e sembra che nessuno dei due lavori. La chiamata nel frammento appropriata è la stessa per le due opzioni e va come segue:

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.... :("); 
     } 
     }); 
    } 

OPZIONE 1:

  • l'interfaccia 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; 
        } 
    }; 
    
  • risultato:

RetrofitError: 401 Unauthorized

OPZIONE 2:

  • l'interfaccia 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); 
    } 
    
  • risultato:

Sembra che sto ricevendo risposta vuota (I solo ottenere "*" per l'ambito). La risposta positiva è simile al seguente:

enter image description here

e intestazione come questo:

enter image description here

Avete delle idee che cosa sto facendo di sbagliato? Qualcuno ha fatto questo?

The official Reddit github wiki manca di esempi Android (ha in quasi ogni altra lingua, però).

risposta

0

Stavo passando lo stesso problema prima e ho fatto questo library per gestire OAuth2 in Android. e la libreria è un'estensione per Retrofit che semplifica il processo di autenticazione con un provider OAuth 2.

+0

Hai usato questa libreria per autenticare utenti di reddit? L'implementazione oauth di Reddit è un po 'insolita, quindi non sono sicuro che la libreria la supporterà. –

+0

In realtà, non l'ho usato su Reddit. Leggi ReadMe in Repo, Se non è stato utile al tuo scopo dimmelo o puoi biforcare il progetto e ciò di cui hai bisogno – abozaid

0

In base all'immagine con la risposta "vuota", mostrando di avere * come scope, sospetto che la tua definizione per la risposta del token di accesso utilizzi la custodia del cammello invece del caso del serpente, quindi il JSON non sta ottenendo caricato correttamente nell'oggetto Java.