Greetings! Old C/Kernel dude here with 2 questions. 1) Using the example app from github for the IOS/Rails app (Humon) I have gotten the rails app working on heroku and on my iPhone and iPhone simulator. GET requests work but that very first user POST request fails. Log extract below:
2014-09-13T20:54:14.899204+00:00 heroku[router]: at=info method=POST path=“/v1/events” host=damp-everglades-3991.herokuapp.com request_id=7dcb3230-1c0a-4ab9-996b-3b6f2d437f28 fwd=“99.103.199.15” dyno=web.1 connect=3ms service=142ms status=401 bytes=741
2014-09-13T20:54:14.759117+00:00 app[web.1]: Started POST “/v1/events” for 99.103.199.15 at 2014-09-13 20:54:14 +0000
2014-09-13T20:54:14.854710+00:00 app[web.1]: Rendered text template (0.1ms)
2014-09-13T20:54:14.833027+00:00 app[web.1]: Processing by Api::V1::EventsController#create as JSON
2014-09-13T20:54:14.833065+00:00 app[web.1]: Parameters: {“name”=>"Ysss ", “lat”=>37.78673118018515, “started_at”=>“2014-09-13T20:53:09.000Z”, “lon”=>-122.406417, “address”=>“120 Stockton St”, “owner”=>{“device_token”=>“B10DA8F7-E1AB-4F23-AF73-A75DE8AA7DE7”}, “event”=>{“name”=>"Ysss ", “started_at”=>“2014-09-13T20:53:09.000Z”, “address”=>“120 Stockton St”, “lat”=>37.78673118018515, “lon”=>-122.406417}}
2014-09-13T20:54:14.852696+00:00 app[web.1]: Can’t verify CSRF token authenticity
2014-09-13T20:54:14.855290+00:00 app[web.1]: Completed 401 Unauthorized in 22ms (Views: 1.7ms | ActiveRecord: 8.7ms)
I know I need to be capturing and sending back in the header something but I have not worked out how yet.
Even though the rails app works on the laptop and heroku none of the tests work. This is a bummer 'cause I want to learn to be a TDD person. Here is a random example. Research says test db not set up right but there is no test:prepare. Any of the tests in the spec directory will fail right out of the box.
jourdanlap:rails jclish$ bundle exec rspec spec/
F
Failures:
factory attendance is valid
Failure/Error: factory = build(factory_name)
ActiveRecord::StatementInvalid:
PG::UndefinedTable: ERROR: relation “attendances” does not exist
LINE 5: WHERE a.attrelid = ‘“attendances”’::regclass
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = ‘“attendances”’::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
./spec/models/factories_spec.rb:6:in `block (3 levels) in <top (required)>’
Finished in 0.25799 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/models/factories_spec.rb:5 # factory attendance is valid
I’m working on a power quality web logger (using arduinos, by now) and you can disable csrf authentication. and i think that’s insecure (maybe i’m wrong).
here is my ApplicationController, it’s Rails 3.2, for Rails 4.x you just need to change:
Many thanks, sir. You just gave me a good clue! This is insecure as you note, but confirms my next course of action: I think I need to 1) Hit the API with a browser 2) See what the X-Header name of the token is 3) Modify the iOS code to a) make a GET at startup to “seed” the mobile app with the session token by pulling the server sent token from the header response and including it with all POST requests. Then I have to either force a load balancer to keep me on one host for the lifetime of a session, or figure out how to restore statelessness to a world where we imposed state by session!
@jclish session management is one of the things i need to learn, but in fact your idea is interesting. here’s the JSON request i’m making to the Rails app:
POST /powerlogs.json HTTP/1.1
Host: localhost:3000
Content-Type: application/json
Cache-Control: no-cache
{ “powerlog”: { “voltage”: 220, “current”: 1 } }
In fact i’ll go deep in this subject, because i can’t afford the risk to expose electrical equipment to web without the needed security.
@nailson, let us go deep together then. By Google, others have written on this very topic. Here is the summary of the day’s research: 1) Be darn sure to understand the difference between “authentication” and “authorization”. 2) Regardless of the backend framework, do not count on headers or sessions based token exchange to keep you safe. 3) In an updated blog article, Bill Patrianakos outlines a solution that looks really good. It is written from the perspective of a client side app developer> See Securing API Keys in a Client Side JavaScript App - Bill Patrianakos.
How I got the example from the book working on local mac and heroku:
Download the zip file from github. Extract it.
X-Code Side:
Follow the .pdf book instructions exactly, they are clear and concise. I only had to do one change to get it working.
In HUMRailsAFNClient.m: Changed
return [self GET:@“events/nearest”
to
return [self GET:@“events/nearests”
You can set up X-code schemes as the book recommends so you can use localhost for the debug build target and your heroku deployment for your alpha testing.
RoR Side:
It works locally out of the box (zip file), I still never have gotten the tests to pass and I am sure that is me. To get it working on Heroku -
in Gemfile added:
gem ‘bourbon’
gem ‘neat’
gem ‘jquery-rails’
Locally compiled the assets.
Then it pushed OK.
To get it working with the App -
Change all references to ‘tb-device-token’ to ‘X-DEVICE-TOKEN’
In application_controller.rb add:
skip_before_filter :verify_authenticity_token, if: :json_request?
after
protect_from_forgery with: :null_session.
That leaves you a bit insecure but that is what I am working out……