目前我正在研究 TMDb API 的实现.有一种方法叫做 User Authentication .我已成功实现第 1 步
Step 1: Generate a Request Token
Start by making an API call to the new token method. This will return a new request token that will be valid for 60 minutes. The request token is not authorized by the user at this stage. Request tokens are API account specific and are the tie between your application and the user in step 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);
}
}
它在控制台中打印回调 url 以及请求 token (如果我将 writer.toString() 转换为 Json 对象)。
但第二部分是通过用户名和密码进行用户身份验证。回调 url 将用户重定向到 TMDb 的登录页面。我通过将回调 url 从控制台复制粘贴到浏览器来测试它。
第 2 步指出:
Step 2: Request Authorization From the User
Once you have a valid request token, your application needs to open a web browser and send them to TMDb. The HTTP response when generating a new token will include a Authentication-Callback header that you can easily use for the redirect.
If the user is not logged in to TMDb, they will be redirected to the login page before being asked to grant your application permission to use their account. Once the user has granted your application permission to use their account, the browser-based part of this process is over and you can return them to your application.
Just like the request for a new token, the approved response will include a Authentication-Callback header which again, is a convenient way to redirect your application back to the API and generate the real session id.
现在我的问题是:如果我有用户名和密码,我可以通过 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 上的页面不是您(第三方应用程序)应该发布任何内容的页面;它是供人类使用的。用户看到此页面时会询问“是否要授予对 [第三方应用程序名称] 的访问权限?如果是,请在此处登录”。您的应用程序无法控制该过程;它有意与您分开,因此用户的凭据永远不会被您拦截或存储。用户批准您后,您将能够获得您使用的不透明 token ( session ID)而不是凭据。
这与三足OAuth基本相同;主要区别是 OAuth 需要一些额外的字段和签名计算,所以这更简单。但它与HTTP basicauth无关。
我相信你想要做的是:
照原样执行第 1 步。但是不要只是获取 Authentication-Callback header ;还解析 JSON 响应并获取“request_token”的值。
通过调用 new session API 检查用户是否已经授权您,再次传递您的 API key 以及先前获取的“request_token”。如果您获得带有“session_id”的成功响应,则您已获得授权,可以跳过其余步骤。
否则,将用户重定向到 Authentication-Callback 中指定的 URL(或者打开浏览器,如果您尚未在浏览器中)。
现在,由于登录/批准过程与您的应用程序是分开的,您如何知道它何时完成?文档对此不清楚,并且没有描述任何方式让您获得有关它的通知(或使 TMDb 重定向回您的应用程序)。您可能只需要在某个合理的时间间隔内轮询结果(即返回步骤 2)。
关于java - 通过 HttpURLConnection 的浏览器身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9478769/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m