【问题标题】:RESTful Api authentication for an android appAndroid 应用程序的 RESTful Api 身份验证
【发布时间】:2015-09-17 19:22:04
【问题描述】:

我有一个任务,我需要使用电子邮件和密码来验证用户并获取访问令牌。我有 api 密钥、秘密和基本 URL。我不需要为作业使用重定向 URL,也没有提供它。我不确定使用哪种方法或使用哪个库。我淹没在丰富的信息中,这让我感到困惑。我需要指出正确的方向......欢迎任何形式的帮助。谢谢

【问题讨论】:

  • 您要求使用 Oauth 1.0 还是 2.0?从你的问题很难判断。 1.0 使用“消费者密钥”和“消费者秘密”(所以我想可能是 1.0),但它需要重定向(可能不需要)。 2.0 不需要重定向(很好),但使用“客户端 ID”和“客户端密码”(不符合要求)。请澄清,以获得进一步的帮助。
  • 查看 OAuth 2.0 规范中的 Resource Owner Password Credentials Grant。我相信这是指令所要求的。它显示了一个示例令牌请求,其中客户端 id(api 密钥......也许)和客户端密码被 base64 编码到授权标头中。您可能想与您的讲师或给您分配作业的人澄清这一点。另请参阅Basic Authentication,了解如何正确制定授权标头
  • 大纲如下
  • 在本练习中,使用此处概述的电子邮件/密码流程来获取访问令牌 xxxxxxxxxxxxxx。请注意,本练习不需要 redirect_uri URL 参数,只需要用户名、密码、client_id 和 client_secret。您不必关心令牌过期或刷新此分配的令牌,您只对响应的 access_token 部分感兴趣。一旦您获得用户的访问令牌,任何后续 API 调用都可以通过身份验证将 Authorization HTTP 标头设置为 OAuth2 ”。
  • 是的,我提供的链接是您想要查看的。用户名和密码作为 form-urlencoded 数据(连同 grant_type)在正文中发送,client_id:client_secret(当然是实际值)在 Authorization 标头中进行 Base64 编码。请参考我提供的资源链接

标签: android json rest oauth oauth-2.0


【解决方案1】:

根据您的 cmets,说明告诉您使用 Resource Owner Password Credentials Grant。您可以在规范中看到example request

 POST /token HTTP/1.1
 Host: server.example.com
 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
 Content-Type: application/x-www-form-urlencoded

 grant_type=password&username=johndoe&password=A3ddj3w

唯一可能看起来很奇怪(如果您从未遇到过的话)是 Authorization 标头值。阅读Basic Authentication。基本上czZCaGRSa3F0MzpnWDFmQmF0M2JWusername:password(实际上是<client_id>:<client_secret>)的base64 编码。

不使用任何外部库(仅标准 Java 库)来发出请求,您可能会有类似

String formData = "username=<uname>&password=<pass>&grant_type=password";
String header = "Basic " + Base64.encodeAsString("<client_id>:<client_secret>");

HttpURLConnection connection
                = (HttpURLConnection) new URL(tokenUrl).openConnection();
connection.setDoOutput(true);
connection.addRequestProperty("Authorization", header);
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestMethod("POST");
connection.setRequestProperty("charset", "utf-8");
connection.setRequestProperty("Content-Length", Integer.toString(formData.length()));

OutputStream out = connection.getOutputStream();
out.write(formData.getBytes(StandardCharsets.UTF_8));

InputStream in = connection.getInputStream();
AccessToken token = new ObjectMapper().readValue(in, AccessToken.class);
System.out.println(token);

out.close();
in.close();

我使用的Base64 不是标准库类。 ObjectMapper 也不是标准库类。我只是用它来解析对AccessToken 类的令牌响应。你可以使用任何你喜欢的解析器。 AccessToken 类只有所有可能的标记值

public class AccessToken {
    public String access_token;
    public String refresh_token;
    public long expires_in;
    public String token_type;
    public String scope;
}

从那里,一旦你有了令牌,任何你想发出的资源请求,你只需要添加一个带有Bearer &lt;access_token&gt;Authorization 标头。

【讨论】:

  • 这很有帮助!我想知道你为 BASE64 使用了哪个库?
  • 这是我使用的后端框架中的一个类。它与我所做的测试无关,但我只是使用了该项目,因此我不必为这个简单的测试创建另一个项目。这门课可能对你没用。虽然看起来 Android 也有一个Base64 class。哦,最后一段,我认为它不符合您的要求。看起来身份验证方案应该是 OAuth2 而不是 Bearer
【解决方案2】:

我建议您使用 retrofit 库来执行此操作。

假设您的 URL 基础是 http://baseurl.com/api,您必须向 /login 执行 GET 请求并传递电子邮件和密码。我假设您的 API 将返回一个用户对象作为 JSON。

API.java

public interface Api {

    @GET("/login")
    public void login(@Query("email") String email, @Query("password"), Callback<User> callback);

}

您需要执行 API 调用的位置:

Retrofit retrofit = new Retrofit.Builder()
    .setEndpoint("http://baseurl.com")
    .build();

Api api = retrofit.create(Api.class);
api.login(email, password, new Callback<User>() {
    @Override
    public void success(User user, Response response) {
        // login logic
    }

    @Override
    public void failure(RetrofitError error) {
        Log.e("Retrofit", error.getMessage());
    }
});

我希望这个例子可以帮助到你。不要忘记阅读retrofit documentation

【讨论】:

  • 我试过了,还是不行。改造简单得令人难以置信……它对我不起作用。
  • 在本练习中,使用此处概述的电子邮件/密码流程来获取访问令牌 xxxxxxxxxxxxxx。请注意,本练习不需要 redirect_uri URL 参数,只需要用户名、密码、client_id 和 client_secret。您不必关心令牌过期或刷新此分配的令牌,您只对响应的 access_token 部分感兴趣。一旦您获得用户的访问令牌,任何后续 API 调用都可以通过身份验证将 Authorization HTTP 标头设置为 OAuth2 ”。
猜你喜欢
  • 2016-10-22
  • 2011-11-28
  • 2010-11-11
  • 2013-08-21
  • 2013-10-07
  • 2018-05-18
  • 1970-01-01
  • 2011-10-02
  • 2014-11-15
相关资源
最近更新 更多