bcwik9 / robinhood-on-rails

A web dashboard for the free trading platform Robinhood using Ruby on Rails and a private API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Missing device token

frakman1 opened this issue · comments

commented

Hi @bcwik9. Thank you for making this! I can't wait to use it.

I just installed this manually on my Mac OSX 10.13.6 (High Sierra) after getting all the ruby issues resolved (rvm, ruby, gem, bundler versions)

After running the local server on port 3000, I attempt to login with my credentials and I get this "Missing device token" error. I get this error both with and without Two Factor Authentication on my account.

image

System details:

$rvm list
=* ruby-2.7.1 [ x86_64 ]

# => - current
# =* - current && default
#  * - default

$ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin17]

$gem --version
3.1.2

$bundle -v
Bundler version 2.1.4

Traceback:

$bundle exec rails server
=> Booting Puma
=> Rails 5.0.7.2 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
DEPRECATION WARNING: Sprockets method `register_engine` is deprecated.
Please register a mime type using `register_mime_type` then
use `register_compressor` or `register_transformer`.
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block in <class:Railtie> at /Users/frak/.rvm/gems/ruby-2.7.1/gems/less-rails-2.8.0/lib/less/rails/railtie.rb:16)
DEPRECATION WARNING: You are using a deprecated processor interface Less::Rails::ImportProcessor.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors
 (called from block in <class:Railtie> at /Users/frak/.rvm/gems/ruby-2.7.1/gems/less-rails-2.8.0/lib/less/rails/railtie.rb:21)
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/stack.rb:35: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/static.rb:113: warning: The called method `initialize' is defined here
Puma starting in single mode...
* Version 3.12.4 (ruby 2.7.1-p83), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started GET "/" for ::1 at 2020-04-25 11:47:17 -0400
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:27: warning: rb_check_safe_obj will be removed in Ruby 3.0
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/abstract_adapter.rb:81: warning: deprecated Object#=~ is called on Integer; it always returns nil
  ActiveRecord::SchemaMigration Load (0.1ms)  SELECT "schema_migrations".* FROM "schema_migrations"
DEPRECATION WARNING: before_filter is deprecated and will be removed in Rails 5.1. Use before_action instead. (called from <class:ApplicationController> at /Users/frak/git/robinhood/robinhood-on-rails/app/controllers/application_controller.rb:5)
Processing by DashboardController#home as HTML
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionview-5.0.7.2/lib/action_view/view_paths.rb:11: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionview-5.0.7.2/lib/action_view/lookup_context.rb:134: warning: The called method `template_exists?' is defined here
  Rendering dashboard/home.html.haml within layouts/application
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/abstract_controller/helpers.rb:68: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_controller/metal/request_forgery_protection.rb:284: warning: The called method `form_authenticity_token' is defined here
  Rendered layouts/_robinhood_login_form.html.haml (3.2ms)
  Rendered dashboard/home.html.haml within layouts/application (54.7ms)
  Rendered application/_favicon.html.erb (1296.5ms)
  Rendered layouts/_flash_message.html.haml (2.5ms)
  Rendered layouts/_side_menu.html.haml (3.7ms)
Completed 200 OK in 1506ms (Views: 1498.8ms | ActiveRecord: 0.0ms)


/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:27: warning: rb_check_safe_obj will be removed in Ruby 3.0
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/abstract_adapter.rb:81: warning: deprecated Object#=~ is called on Integer; it always returns nil
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:27: warning: rb_check_safe_obj will be removed in Ruby 3.0
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/abstract_adapter.rb:81: warning: deprecated Object#=~ is called on Integer; it always returns nil
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:27: warning: rb_check_safe_obj will be removed in Ruby 3.0
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/abstract_adapter.rb:81: warning: deprecated Object#=~ is called on Integer; it always returns nil
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/sqlite3_adapter.rb:27: warning: rb_check_safe_obj will be removed in Ruby 3.0
/Users/frak/.rvm/gems/ruby-2.7.1/gems/activerecord-5.0.7.2/lib/active_record/connection_adapters/abstract_adapter.rb:81: warning: deprecated Object#=~ is called on Integer; it always returns nil
Started POST "/robinhood_login" for ::1 at 2020-04-25 11:47:29 -0400
Processing by RobinhoodController#login as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"xxxx", "username"=>"xxxx", "password"=>"[FILTERED]", "commit"=>"Log in"}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6503  100  6503    0     0   2360      0  0:00:02  0:00:02 --:--:--  2359
Completed 500 Internal Server Error in 5381ms (ActiveRecord: 0.0ms)



RuntimeError (Missing device token):

app/models/concerns/robinhood.rb:48:in `set_account_token'
app/controllers/robinhood_controller.rb:12:in `login'
  Rendering /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
  Rendering /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (2.3ms)
  Rendering /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.1ms)
  Rendering /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.1ms)
  Rendered /Users/frak/.rvm/gems/ruby-2.7.1/gems/actionpack-5.0.7.2/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (23.9ms)
/Users/frak/git/robinhood/robinhood-on-rails/app/models/concerns/robinhood.rb:48: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
/Users/frak/.rvm/gems/ruby-2.7.1/gems/web-console-3.7.0/lib/web_console/exception_mapper.rb:31: warning: in `eval'
^C- Gracefully stopping, waiting for requests to finish
=== puma shutdown: 2020-04-25 11:52:41 -0400 ===
- Goodbye!
Exiting

I'd love to finally get this working. Please let me know if you need any more information.
Thank you!

Since Robinhood doesn't support an official API, they are constantly changing how their login process works. They previously had window vars in js that were included in the HTML response on their login form. I relied on those variables to be able to log in. Now it looks like they are gone (replaced mostly by cookies and other JS scripts it seems), which is why you are seeing that error.

I went ahead and updated the master branch with a login method that works... for now. Like I said, since it's an unofficial API, it makes it difficult to create a reliable connection method.

Let me know if you have any issues.

commented

Thank you for quickly resolving this. I realize this is an "as-is" and "best-effort" service given the unofficial nature of the API. I am very grateful to you for making this possible.
Thanks again!

commented

@bcwik9 Unfortunately, this didn't work for me with 2FA enabled.

I entered my username/password and clicked on Login, then it asked me to enter the security code. So I filled out the form again, this time entering the security code (twice). For some reason, there were two fields entitled 'Security Code'. Now I get this error:

image

commented

Update.
If I disable 2FA in Robinhood Settings->Security:
image

... and login with username/password, I still get sent a code via SMS with a slightly different wording "Your Robinhood code is xxx. This code will expire in 5 minutes." instead of the previous "Robinhood Code: xxxx." when 2FA was enabled.

Now, the webpage asks me to enter my security code (this time only once) in the new Security Code field and it works!

So as long as I disable 2FA, I can get this to work. Better than nothing I suppose haha
¯\_(ツ)_/¯

@frakman1 @bcwik9 I played around with this for a few minutes. With 2FA On, the top field is the 2FA security code, the bottom field, challenge code, is not required (see URL param) but a bug is preventing the form submission without a value.

To bypass, I open the inspector and remove "required" from the challenge code html node (bottom) and fill user/pass/(top) security code (with 2FA value). It works.

@frakman1 @bcwik9 I played around with this for a few minutes. With 2FA On, the top field is the 2FA security code, the bottom field, challenge code, is not required (see URL param) but a bug is preventing the form submission without a value.

To bypass, I open the inspector and remove "required" from the challenge code html node (bottom) and fill user/pass/(top) security code (with 2FA value). It works.

Thanks for the input. I had a moment to fix the 2FA issue in the master branch today.

commented

To bypass, I open the inspector and remove "required" from the challenge code html node (bottom) and fill user/pass/(top) security code (with 2FA value). It works.

I love the ingenuity!