当前位置: 首页 > 知识库问答 >
问题:

Reddit oAuth 2适用于Android“无用户”应用程序

邹山
2023-03-14

我试图实现Reddit oAuth2(每一个应用程序,利用Reddit的内容必须有这个实现)在基于Android的“无用户”应用程序,我遵循的指导方针。

  1. 我注册了一个应用程序,并获得了相应的client_id.
  2. 为了正确编写Android代码,我遵循以下API指南和更新指南。

因此,我编写了两种方法来解决这个问题,似乎都不起作用。对于这两个选项,适当片段中的调用是相同的,如下所示:

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

似乎我得到的响应是空的(范围只得到“*”)。成功的响应如下所示:

标题如下所示:

你知道我做错了什么吗?有人这么做过吗?

官方的Reddit github维基缺少Android的例子(不过几乎所有其他语言都有)。

共有1个答案

樊浩初
2023-03-14

我以前也经历过同样的问题,并在Android中把这个库制作成handel OAuth2。该库是一个改型的扩展,它简化了针对OAuth2提供程序的身份验证过程

 类似资料:
  • 当我在Android手机上调试应用程序时,我绝对没有遇到任何错误,但在AVD上,我一开始就得到了一个NullPointerException()。我的Android设备在22 API的Lollipop(5.1.1)上运行,我的AVD在28 API的Pie(9.0)上运行。我在gradle中将最小SDK设置为21,编译SDK设置为28。 这是错误: E/AndroidRuntime:致命异常:主进程

  • 我只是在听讲座:(这是错误消息 E/Android运行时: 致命异常: 主进程: 8893 java.lang.空指针异常: 尝试调用虚拟方法 '布尔 java.lang.字符串.contains(java.lang.CharSequence)'.java.java.java 在空对象引用上android.os.AsyncTask.access$900(AsyncTask.java:192) at

  • 问题内容: 我正在开发一个项目,该项目需要解析一些受保护的网页中的数据。为了获得对这些页面的访问权限,我必须克服SAML身份验证形式(Shibboleth)。是否有人能够在Android(Java)中实现此标准?我已经读过这个线程:Android的SAML客户端实现? 但这并不能给我一个很好的解决方案。实际上,我需要 获取某些受保护网页的数据 以便对其进行解析,而不是让用户看到此类网页的内容。因此

  • 一个使用Jersey在Java中构建的方法,它接受两个参数并存储在数据库中,它可以和postman一起正常工作,但当我在Android应用程序中使用它时,它不起作用。我试图通过截击和改装发送请求。 服务器端代码: Android代码: 公共无效寄存器(最终字符串用户名、最终字符串密码){ 邮差回应 截击请求: 公共无效寄存器Volley(最终字符串用户名,最终字符串密码){

  • 问题内容: 在过去十年中,有少数人提出了类似的问题,但没有人给出任何答案。我需要编写一个收集和存储RSRP,RSRQ,CINR和Cell ID的Android应用。答案必须与手机硬件允许的精度一样(我正在三星银河S5上进行测试),因为我需要使用这些值进行后处理统计。 有谁知道如何使用telephonyManager或CellSignalStrengthLte获得RSRP?还是有另一种也许更好的方式

  • 我正在构建基于Web的多租户SaaS应用程序。应用程序已在我的租户中注册,每个订阅Office 365的客户都将在Azure AD中获得服务主体对象。 我在客户租户中从外部帐户(Microsoft帐户)登录时遇到问题。 我创建了一个示例,并试图看看我可以从访问令牌中获得什么。 示例包含一个使用 MSAL 库处理身份验证的客户端应用程序 (.js) 和两个具有受保护终结点的 API。我还创建了三个独