I have a Rails app that makes calls to the Evernote API. I want to write RSpec tests for these calls. What's the best way of doing that? I know I can use Webmock or VCR, but - unless I'm mistaken - I would not then be able to have self-contained tests in my repository without pushing either my secret key or a cached oauth response.
VCR provides a simple way to filter out sensitive data like secret keys:
https://relishapp.com/vcr/vcr/v/2-4-0/docs/configuration/filter-sensitive-data!
Related
I wonder what is the difference between REST Client like Postman and browser? I want to make API calls but I dont understand why I have to use a REST Client instead of a browser.
A browser permits to create simple GET calls, you invoke a url and obtain the response.
A REST Client permits more possibilities like:
to construct every type of REST/HTTP call such as POST,PUT and DELETE,
add headers to the calls,
build a body for the calls (a json/xml or whatever of want one).
It's a tool more sophisticated.
You can install a standalone one like:
Postman
Insomnia
or install a browser extension for Firefox and Chrome like:
Resting
Rester
Disclaimer: I'm the creator and maintainer of Resting
I am building a rest api using mod-wsgi and werkzeug. I am able to test the api for get request locally. But, not able to do the same for POST request. Any way to do it?
check out https://www.postman.com/
or https://insomnia.rest/
you can store calls, document, make test suites, and much more
We have a couple of REST APIs that need to be tested. APIs are owned by some other team. Currently, we use Node.js with Ava to test our APIs.
We have recently started exploring Elixir as our scripting language. We would like to experiment with Elixir to test REST API. The question here is - how to test external web services/REST API with Elixir?
Every Google search around Elixir testing refers back to ExUnit which is basically for unit testing of Elixir apps. We don't have any app written in Elixir or in Phoenix.
All we want to do is to test API end-to-end. How to do that with Elixir? Which libraries to use? I know I can make network calls from my tests written in ExUnit and verify the API behavior, but not sure if it is the right way.
NOTE: We already have JMeter in place for load testing of API but we wish to keep functional testing separate from load testing due to complex workflows involved with API.
I think what you descried in the answer is the right way.
You can use ExUnit as the test running and reporting framework. In ExUnit you can do whatever you want, make network calls, even parse the DOM. For testing a REST API you can use HTTPoision and assert on status code and response body.
Create a new mix project
mix new api_test
Add HTTPoison dependency to mix.exs
...
defp deps do
[
{:httpoison, "~> 1.6"}
]
end
...
Run mix deps.get to get HTTPoison installed.
Add a test in test/api_test_test.exs
defmodule ApiTestTest do
use ExUnit.Case
doctest ApiTest
test "API alive" do
resp = HTTPoison.get!("https://api.github.com")
assert resp.status_code == 200
end
end
Run the tests with mix test from the project root.
I am developing a REST API, and have found a very interesting problem.
When I access the resources in a web browser (in my case Chrome), everything works fine. However, when I access the resources using a REST client (Google Chrome plugin, web-based client, and a Java applet), NONE of the variables pass to the API. This happens both with GET and POST methods.
I have absolutely no idea why this would be the case, and it's proving very difficult to test the methods before putting them into production (especially with POST methods).
Please help!
At first glance it sounds it could be 2 things:
You are not correctly passing API parameters via your client or
applet
A problem with authentication or cookie management. Does the API require any type of authorization?
Are you forgetting to set a necessary HTTP header?
Do you have control of the API also or is it a third party API? If so, do the params arrive at all or do they arrive empty? What's the error code? - a 403 not authorized (which would make sense if the key doesn't pass) or something else due to missing params.
Try the intermediate step of doing it with CURL form the command line - that'll give you more detail on what's coming back.
I am trying to build a rails 3 back-end for a mobile application. However, I am new to creating rails 3 apps.
Users will need to have a session on the server, but I have no support for normal cookies, so I would need to send a session_id along with every request.
What kind of authentication system should I use in rails 3, is there a gem?
I have read that in rails 2 it was possible to set the session_id from the URL, but that this function is stripped from rails 3 due to security concerns. Is this even true? If there is a way to do this, I am very interested, despite the possible security holes.
Usually I'd use HTTP Digest authentication to solve this problem. Most of the Rails authentication plugins (such as Authlogic, probably Devise) will support HTTP Basic or Digest authentication though a plugin. In this way, you don't have to worry about expired cookies and the like.
You can also pass an api_key parameter instead of a session id.
In many cases I've used an api key as the HTTP Basic username. This gives clean URLs and session-less authentication.
The security problem you're probably referring to is Cross-Site Request Forgery. It is indeed a real problem. Its why you hide actions with side effects (create, update, destroy) behind forms with a CSRF token. Otherwise a malicious link can perform unintended actions to a site that you're already authenticated to without needing to know your credentials.
As long as your API key isn't easily discoverable by anyone in an automated fashion, the risk should be minimal.
Update
A small update: Devise no longer has authentication_token as its implementation was deemed too insecure. A good alternative is Brian Auton's suggestion.
The summary of his method is that he generates an authentication_key AND authentication_secret in a separate model. You then authenticate by sending both your key and secret, if a match is found you are temporarily signed in as a user.
In your application controller this looks like so:
class ApplicationController < ActionController::Base
before_filter :authenticate_from_token
protected
def authenticate_from_token
if current_token.try :authenticatable
sign_in token.authenticatable, store: false
end
end
def current_token
AuthenticationToken.find_authenticated({
secret: (params[:secret] || request.headers[:secret]),
secret_id: (params[:secret_id] || request.headers[:secret_id]),
})
end
end
The authenticatable of the token in this case is a User model, or any other thing that has been made authenticatable (the tokens are polymorphic). As you can see it can easily be made to work with Devise.
I like this method a lot and have implemented it in a recent API. Do read up on it on his website.
Old answer
Outdated answer, kept for reference to older versions of Devise: Devise has a 'authentication_token' column which I can use for authenticating a user. I could have a login API method which I will send a username + password too, then get the token back and store that locally to sign all my other calls with. It basically is a cookie system, but one that is directly supported by Devise.
On top of this I could re-generate the token on either every call or on every 'session'.