通过HttpURLConnection进行浏览器身份验证
目前我正在研究TMDb API的实现。 有一种称为用户认证的方法。 我已经成功实施了第一步
步骤1:生成请求标记
首先对新的令牌方法进行API调用。 这将返回一个新的请求标记,该标记将在60分钟内有效。 请求令牌在此阶段未被用户授权。 请求令牌是API帐户特定的,并且是第2步中您的应用程序和用户之间的联系。
对于第1步,我有以下代码:
URL url = new URL("http://api.themoviedb.org/3/authentication/token/new?api_key=the_key");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringWriter writer = new StringWriter();
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
}
reader.close();
Map<String, List<String>> headerFields = connection.getHeaderFields();
String callBackUrl = null;
for(Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
if(entry.getKey() != null && entry.getKey().equals("Authentication-Callback")) {
callBackUrl = entry.getValue().get(0);
}
}
它与Request Token一起在控制台中打印回调url(如果将writer.toString()
转换为Json对象)。
但第二部分是通过用户名和密码进行用户认证。 回调URL将用户重定向到TMDb的登录页面。 我已通过将控制台的回调URL复制到浏览器进行测试。
第2步说明:
第2步:请求来自用户的授权
一旦你有了一个有效的请求令牌,你的应用程序需要打开一个Web浏览器并发送给TMDb。 生成新令牌时的HTTP响应将包含可轻松用于重定向的Authentication-Callback标头。
如果用户没有登录到TMDb,他们将被重定向到登录页面,然后被要求授予您的应用程序使用其帐户的权限。 一旦用户已授予您的应用程序使用其帐户的权限,此过程中基于浏览器的部分即告结束,您可以将其返回给您的应用程序。
就像对新令牌的请求一样,已批准的响应将包含一个Authentication-Callback标头,这也是将应用程序重定向回API并生成真实会话标识的一种便捷方式。
现在我的问题是:如果我有用户名和密码,我可以通过HttpURLConnection或其他方式验证该用户吗?
我试过这个:
url = new URL(callBackUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
BASE64Encoder encoder = new BASE64Encoder();
String usernamepassword = "myusername" + ":" + "mypassword";
String encodedAuthorization = encoder.encode(usernamepassword.getBytes());
connection.setRequestProperty("Authorization", "Basic "+ encodedAuthorization);
headerFields = connection.getHeaderFields();
for(Map.Entry<String, List<String>> entry : headerFields.entrySet()) {
System.out.println(entry.getKey() + " : " +entry.getValue());
}
但在控制台中我得到了:
null : [HTTP/1.1 404 Not Found]
Status : [404 Not Found]
X-Frame-Options : [sameorigin]
Date : [Tue, 28 Feb 2012 08:30:17 GMT]
Vary : [Accept-Encoding]
X-Cascade : [pass]
Content-Length : [7835]
X-XSS-Protection : [1; mode=block]
Set-Cookie : [tmdb.session=BAh7CUkiD3Nlc3Npb25faWQGOgZFRiJFNGRkMjc5ODYwMjJmYWYwZDlmOGE5%0AOTVjY2E0NWFjMzhhYTRiOGFjOGJiYjQ5ZGFhNzExNDdkMGM4MWNhZGUyMEki%0ADWxhbmd1YWdlBjsARkkiB2VuBjsARkkiC2xvY2FsZQY7AEZJIgd1cwY7AEZJ%0AIg5sb2dnZWRfaW4GOwBGRg%3D%3D%0A; path=/; expires=Thu, 29-Mar-2012 08:30:17 GMT; HttpOnly]
Content-Type : [text/html;charset=utf-8]
Connection : [keep-alive]
Server : [nginx]
如你看到的:
Status : [404 Not Found]
所以最后的程序并不富有成效。
我是否以错误的方式执行身份验证?
我非常感谢你的建议。
提前致谢。
我对TmDB不熟悉,但是我已经阅读了他们的用户认证过程页面,我认为你误解了它。
他们明确表示,他们不希望第三方应用程序存储用户名/密码凭据,或者将其传递到请求中(“这个系统的好处是我们永远不会通过空中传递用户名或密码或要求一个第三方应用程序在本地存储它“)。 callbackUrl中的页面不是你第三方应用程序应该发布的内容; 它是供人使用的。 用户看到此页面,询问“您是否想授予[第三方应用程序名称]的访问权限?如果是,请在此登录”。 您的应用程序无法控制该过程; 它故意与您分开,以便用户的凭据永远不会被您截取或存储。 一旦用户批准了您,您将能够获得您使用的不透明令牌(会话ID),而不是凭据。
这与三段式OAuth基本相同。 主要区别在于OAuth需要一些额外的字段和签名计算,所以这更简单。 但它与HTTP basicauth无关。
我相信你想要做的是这样的:
像你一样做第1步。 但是不要只抓取Authentication-Callback头; 也解析JSON响应并获取“request_token”的值。
通过调用新的会话API,检查用户是否已经授权您,再次将API密钥与先前获取的“request_token”一起传递。 如果您通过“session_id”获得成功响应,则您已获得授权,您可以跳过其余步骤。
否则,将用户重定向(或者如果你不在一个浏览器中,则打开浏览器)到Authentication-Callback中指定的URL。
现在,由于登录/审批流程与您的应用程序是分开的,您怎么知道它何时完成? 此文档尚不清楚,并没有描述任何方式让您获得关于它的通知(或将TMDb重定向回您的应用程序)。 您可能需要在某个合理的时间间隔内轮询结果(即返回步骤2)。