2015-06-30 70 views
1

我有一个任务,我需要使用电子邮件和密码来认证用户并获取访问令牌。我有api密钥,秘密和基本URL。我不需要为该作业使用重定向网址,因此未提供该网址。我不确定使用哪种方法或哪个库。我沉浸在丰富的信息中,令我感到困惑。我需要指出正确的方向......任何形式的帮助都会受到欢迎。谢谢Android应用程序的RESTful Api认证

+0

您是否需要使用Oauth 1.0或2.0?你的问题很难说清楚。 1.0使用“消费者密钥”和“消费者机密”(所以我想可能是1.0),但它需要重定向(可能不是)。 2.0不需要重定向(好),但使用“客户端ID”和“客户端密钥”(不符合要求)。请澄清,以获得进一步的帮助。 –

+0

它是oauth 2.0。 –

+0

查看OAuth 2.0规范中的[资源所有者密码凭据授予](http://tools.ietf.org/html/rfc6749#section-4.3)。我相信这是指令要求的。它显示了一个示例令牌请求,其中客户端ID(api key ...也许)和客户端密钥以base64编码到授权标头中。您可能想要与您的教师或任何给予您的任务分清楚。另请参阅[基本身份验证](https://en.wikipedia。org/wiki/Basic_access_authentication)关于如何正确制定授权标题 –

回答

4

根据您的意见,说明会告诉您使用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 <access_token>添加Authorization头。

+0

这非常有帮助!我想知道你使用BASE64的库是什么? –

+0

这是我使用的后端框架中的一个类。它与我做的测试没有任何关系,但是我只是使用了这个项目,所以我不必为这个简单的测试创建另一个项目。这个班对您来说可能没用。虽然看起来Android也有[Base64类](http://developer.android.com/reference/android/util/Base64.html)。哦,最后一段,我认为它不符合你的要求。看起来认证方案应该是“OAuth2”而不是“承载者” –

0

我建议你使用retrofit库来做到这一点。

假设您的网址为http://baseurl.com/api,您必须执行GET请求以/登录传递电子邮件和密码。我假设你的API会以JSON的形式返回一个User对象。

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

+0

我试过这是行不通的。改造简单太简单了,但是它不适用于我。 –

+1

为了本练习的目的,请使用此处列出的电子邮件/密码流来获取访问令牌xxxxxxxxxxxxxx。请注意,本练习不需要redirect_uri URL参数,只有用户名,密码,client_id和client_secret。您不必关心令牌过期或为此任务负责刷新,您只对响应的access_token部分感兴趣。一旦您为用户获取访问令牌,任何后续API调用都可以通过将授权HTTP标头设置为OAuth2 “。 –