kurenn / market_place_api

The API on Rails tutorial application
142 stars 68 forks source link

Hitting endpoints w/ curl #66

Closed TravisSiebenhaar closed 8 years ago

TravisSiebenhaar commented 8 years ago

Hey guys,

I have been trying to figure this out for awhile now and I have yet to find a solution. I'm trying to access my api with curl commands and had no such luck. Would anyone be so kind as to supply some curl commands for signing a user in, updating their information and/or deleting? I've been attempting to update a users info by hitting the following:

curl http://api.host_api.dev/users/1 -X PUT -d first_name="Buttface" -H "Authorization: Token EDeWkWYaAx6DrD1piBzS"

However, I get the code {"errors":"Not authenticated"}. This is obviously because our authenticate_with_token! method looks for the presence of a current_user. So I figured I would try and set a current_user through creating a new session but have not had luck. Any help would be greatly appreciated.

I know this isn't really an issue with the book, I have actually found it VERY helpful and loving it.

Thank you for any time you spend assisting me.

kurenn commented 8 years ago

Are you sure the current_user or that the token you are using is working well?

TravisSiebenhaar commented 8 years ago

The current_user method should be working as all tests pass and I have been following the book exactly. I think the issue is that I might not be signing in correctly. To my understanding the Sessions controller is handling the signing in. So I will be hitting the http://api.host_api.dev/users/sign_in route. It should then take session email & password. Here is the latest curl request I made: curl -v -H "Content-Type: application/json" -u "georgette@boehm.info":"testing1" http://api.host_api.dev/users/sign_in. The response to this was:

*   Trying 127.0.0.1...
* Connected to api.host_api.dev (127.0.0.1) port 80 (#0)
* Server auth using Basic with user 'georgette@boehm.info'
> GET /users/sign_in HTTP/1.1
> Host: api.host_api.dev
> Authorization: Basic Z2VvcmdldHRlQGJvZWhtLmluZm86dGVzdGluZzE=
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type: application/json
> 
< HTTP/1.1 200 OK
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< ETag: W/"7cb2c1e738acd52df0173c3744f8c702"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: feab313a-ef52-42a2-9b92-3135b3efbf73
< X-Runtime: 0.020675
< Date: Wed, 24 Feb 2016 18:49:22 GMT
< Connection: close

After that I try and make a PUT call to that user to change his information and I get back "Not authenticated"

This is where I am getting stuck because I dont quite know how to appropriately pass my users email and password to sign them in. I have tried other 'sign in' examples and haven't had any luck. Just wondering if you could provide an example of the curl command you would use to sign in. I'm almost certain the issue is more a User(Me) issue than my code.

Thank you for taking the time to answer my questions @kurenn

casimcdaniels commented 8 years ago

@Nappstir You should be using JSON to pass params into the request, rather than in the URL as query string

Why? The controllers are setup to take a params[:user][...]. What you are doing is passing the values as params[...], e.g params[first_name] using query_string.

An example:

curl -H "Accept: vnd.marketplace.v1" -H "Content-Type: application/json" -X POST -d \
'{"session":{"password":"password123","email":"test@example.com"}}' localhost:3000/api/sessions

{"id":6,"email":"test@example.com","created_at":"2016-02-24T18:39:29.107Z","updated_at":"2016-0224T19:01:02.042Z","auth_token":"bBf3ysFfyTRXscBywPs","first_name":"test","last_name":"user"}

Then you can take the auth_token you retrieved and pass it through the authorization header, like so

curl -H "Accept: vnd.marketplace.v1" -H "Content-Type: application/json" -H "Authorization: bBf3ysFfyTRXscBywPs" -X PUT -d \
'{"user":{"first_name":"bob"}}' localhost:3000/api/users/6

*Alternatively, if you don't want to use JSON (Why not? It's a JSON api :P) you can pass params into the URL like

http://localhost:3000/api/users/?users[first_name]=dave

TravisSiebenhaar commented 8 years ago

@cmcdaniels Thank you for your answer. I have tried using JSON to pass the params into the request but I get a 500 internal server error response. This was exact format was the format that I attempted first, as it seemed like the reasonable to sign in my user. Here is the curl command user: curl -v -H "Content-Type:application/json" -X POST -d '{"session":{"password":"testing1","email":"georgette@boehm.info"}}' http://api.host_api.dev/users/sign_in Here is the response that I receive:

*   Trying 127.0.0.1...
* Connected to api.host_api.dev (127.0.0.1) port 80 (#0)
> POST /users/sign_in HTTP/1.1
> Host: api.host_api.dev
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type:application/json
> Content-Length: 66
> 
* upload completely sent off: 66 out of 66 bytes
< HTTP/1.1 500 Internal Server Error
< Content-Type: text/html; charset=utf-8
< Content-Length: 64534
< X-Request-Id: 9b381dad-1e45-43c9-ae27-4e91486e2457
< X-Runtime: 0.126446
< Date: Wed, 24 Feb 2016 19:24:38 GMT
< Connection: keep-alive

Unsure why I am getting an INternal Server Error.

casimcdaniels commented 8 years ago

@Nappstir Think you're getting confused with devises built in sessions and the controller built in the tutorial. If you're following the tutorial, then use http://api.host_api.dev/sessions/ to create your "login" session. As it is written you are trying to post to devises controller, which is a login to the client side and not the api of your site.

If you want to use the users/sign_in route for authentication, you will need to extend the Devise Controller and implement what was done in the tutorial (JSON response, and some params).

TravisSiebenhaar commented 8 years ago

Oh man! @cmcdaniels good catch! I knew it was a user error. I was trying to hit Devise controller and not the sessions controller. This was the curl command used to successfully sign-in: curl -v -H "Content-Type:application/json" -X POST -d '{"session":{"password":"testing1","email":"georgette@boehm.info"}}' http://api.host_api.dev/sessions/ Which returns the user w/ auth_token as specified in sessions controller: {"id":1,"email":"georgette@boehm.info","first_name":"Chesley","last_name":"Aufderhar","user_name":"ora","created_at":"2016-02-23T21:35:49.561Z","updated_at":"2016-02-24T19:56:11.511Z","auth_token":"Rz1FQttabjZx_1HFrKtS"}

One last questions and I should be good. Now that I have received my users auth_token, how would I perform and update on this user with that auth_token? Thanks a million for your time @cmcdaniels

casimcdaniels commented 8 years ago

@Nappstir Glad it's working now! =)

To update the user identified by auth_token and ID, you will do what I said above with a PUT like so. Take note of the id at the end of the url and the json format.

curl -H "Accept: vnd.marketplace.v1" -H "Content-Type: application/json" -H "Authorization: Rz1FQttabjZx_1HFrKtS" -X PUT -d \
'{"user":{"first_name":"chell"}}' http://api.host_api.dev/users/1
TravisSiebenhaar commented 8 years ago

This worked perfectly! I was close, I just wasn't quite passing the Authorization token appropriately! I know I keep asking questions, and I appreciate you answering them. So when we are destroying a session (signing a user out) We are looking to pass the auth_token in params, find that user with the auth_token, generate a new one, save.

Oddly enough, the auth_token for that user has changed when I take a look at it in the DB. However, If I try to run be rake db:reset It will tell me that there is one other session using the DB. I dont think I am appropriately destroying the session. I hate to do this, but if you could show me another example of destroying a session that would be great. I know that we need to include sessions/:id..

Here is what I have tried: curl -v -s -H "Content-Type: application/json" -H "Authorization: Rz1FQttabjZx_1HFrKtS" -X DELETE -d '{"id":"Rz1FQttabjZx_1HFrKtS"}' http://api.host_api.dev/sessions/ > temp.html

I'm confused because idk if I should pass id as a json object or put the auth_token right into the url http://api.host_api.dev/sessions/:auth_token. Just very new with curl. Thanks @cmcdaniels

casimcdaniels commented 8 years ago

@Nappstir the inability to run rake db:reset has nothing to do with the sessions stuff, what it means is that some other process on your machine is using the database. In the case of using prax, you want to call "prax stop".

As for the curl, that is correct, except you do not need to pass the authorization header, since you will be passing the auth_token as localhost:3000/sessions/izHzEgChUV3SEJL7FrV3 for example. As long as you receive a 204 error, and your logs don't show a failure to commit the change in authentication_token, you can safely say the session was destroyed.

TravisSiebenhaar commented 8 years ago

That makes sense. @cmcdaniels You have been a huge help I must say. Thank you for your time answering these questions. I think this issue, although not one pertaining to the guide, will be of great service to those who are learning how to build api's for the first time.