Reddit oAuth 2 for Android" userless"应用Retrofit

时间:2015-07-28 15:07:53

标签: android oauth oauth-2.0 retrofit reddit

我正在尝试实施Reddit oAuth2(每个使用Reddit内容的应用都必须拥有此implemented)基于Android且无用户使用#39;应用程序和我遵循指南。

  1. registered an app并获得相应的client_id
  2. 我正在对API guidelinesthis for Retrofit进行此操作,以便正确编写Android代码。
  3. 因此,我已经为这个问题编写了两种方法,似乎两种方法都不起作用。相应片段中的调用对于两个选项是相同的,如下所示:

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

    选项1:

    • 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;
           }
       };
      
    • 结果:

      

    RetrofitError:401 Unauthorized

    选项2:

    • 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);
      }
      
    • 结果:

    似乎我得到空的回应(我只得到&#34; *&#34;作为范围)。成功的回应如下:

    enter image description here

    和标题如下:

    enter image description here

    你有什么想法我做错了吗? 有人这样做过吗?

    The official Reddit github wiki缺少Android示例(几乎所有其他语言都有)。

2 个答案:

答案 0 :(得分:0)

之前我遇到了同样的问题,并在Android中将此library转换为handel OAuth2。该库是Retrofit的扩展,简化了对OAuth 2提供程序进行身份验证的过程。

答案 1 :(得分:0)

根据您的图像使用&#34;空&#34;响应,显示您将*作为范围返回,我怀疑您对访问令牌响应的定义是使用驼峰案例而不是使用蛇案例,因此JSON未正确加载到Java对象中。