I want to caching api responses like
sitename.com/posts.json
for example for 5 minutes, where I must configure Rails and maybe what external tools I must use
just add
caches_page :posts, :expires_in => 5.minutes
it's explained decently on http://guides.rubyonrails.org/caching_with_rails.html#page-caching
Notice that expires_in only works with memcached as the cache store, AFAIK.
Related
This gem ("devise_token_auth") is used for token authentication for applications using JSON APIs for front-end development.
Can we use this gem for server side rendering? If yes, then how to add the token from a previous response to the current request?
I don't know if this is still a pressing matter for you, but I'd like to throw in some advice.
For your API you can throw in devise_token_auth and it will do what everything you need for authentication there.
And if you need authentication with server-side rendering of pages (such as login forms, reset password forms, etc.) just throw in regular devise too. It will work with your exact same User model and table, and there will be little friction to get things up and running with the same resources you use with devise_token_auth.
Gemfile
#autentication and authorization
gem 'devise', '~> 3.5', '>= 3.5.6'
gem 'devise_token_auth', '0.1.37'
Then run
bundle
Run the installer for devise:
rails generate devise:install
Then generate your user model:
rails generate devise User
Install devise_token_auth now:
rails g devise_token_auth:install User "auth"
And make sure your database is migrated:
rake db:migrate
I think devise_token_auth may overwrite your user model, I'm not certain, but if it does, keep the migrations for devise_token_auth only and ignore the migrations for Devise.
Then make sure your routes.rb matches this:
Rails.application.routes.draw do
devise_for :users
root "home#index"
namespace :api, defaults: { format: :json } do
namespace :v1 do #I namespace my routes
mount_devise_token_auth_for "User", at: "auth"
end
end
end
devise_for must come before mount_devise_token_auth.
Then just refer to the official devise and devise token auth documentation to get both solutions working for you.
Hope this helps anyone who reaches this point and has a need to authenticate users on mobile app and on browser web app.
I'm building an API with Rails 4 and I really want to create a Batch request method to not overload my app when doing a bunch of ajax requests.
The Railscasts shows how to do it in a simple way but there's a lot of stuff missing.
I also tried the batch_api gem but I wasn't successful integrating it with my application.
Any ideas?
I know it's being late to answer this question but I recently used batch_api gem with my Rails API (rails 5.0.0 and Ruby 2.0) and it works find with me.
What you need to do is follow the instruction of this document:
https://github.com/arsduo/batch_api
Shortly:
1- You need to add the batch_api gem to your application GemFile.
2- You need to add the required middleware configuration in you application.rb file:
config.middleware.use BatchApi::RackMiddleware do |batch_config|
# you can set various configuration options:
batch_config.verb = :put # default :post
batch_config.endpoint = "/batchapi" # default /batch
batch_config.limit = 100 # how many operations max per request, default 50
# default middleware stack run for each batch request
batch_config.batch_middleware = Proc.new { }
# default middleware stack run for each individual operation
batch_config.operation_middleware = Proc.new { }
end
3- Then restart your rails server.
Make sure to insert the new middleware in the appropriate location, in my case I needed to include it before "ActionDispatch::RequestId" middleware.
config.middleware.insert_before "ActionDispatch::RequestId", BatchApi::RackMiddleware
because I wanted to include X-Request-ID header in each request in the Batch request and this ID will be returned in each response so that I could know the response for each request in the Batch (note that the responses will be executed sequentially depending on the sequence each request in the Batch).
Apparently the batch_api gem doesn't work with rails 4 yet, but there is a fork that was started to update it to rails 4 and ruby 2.0.
https://github.com/easyPEP/batch_api/tree/feature_ruby_2
I got an API that I have developed using Rails 3 and Devise. I am using tokens (token_authenticatable) for authentication for requests made to the API from a client. I want to be able to switch between users in the requests just be replacing the token.
I heard about a setting called :stateless_token (boolean) but I cannot figure out where to put this setting. Is there another way?
If found the token_authenticatable here:
https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/token_authenticatable.rb
If found info about the stateless_token here:
http://rdoc.info/github/plataformatec/devise/master/Devise/Models/TokenAuthenticatable
stateless_token is deprecated as of now. This is the new form (it allows more auth strategies to be stateless):
# config/initializers/devise.rb
config.skip_session_storage = [:token_auth]
You can also edit the file /config/initializers/devise.rb and put (or uncomment, if already there) the following line:
config.stateless_token = true
It should be an option in your devise_for line in the routes file.
devise_for :users, :stateless_token => true
Let me know if that works,
In this page of documentation for devise it says that "TokenAuthenticatable adds the following options to devise_for:" with stateless token being one of them.
Also here is a link to the devise_for documentation
I am trying to split my current Ruby on Rails 3 web-application and it's web-services (API). My web-application is running on Heroku and implements API as a namespaced route within my application. For example /events returns a HTML page and /api/v1/events returns a JSON data.
According to some best practices, I want to split those into two different applications. I have chosen Sinatra to implement the API application. It works now for simple requests where authentication is not required.
My Ruby on Rails 3 application is using Devise to authenticate users. There's also ability to login with Facebook account. Now what I want to achieve, is HTTP Basic Authentication of users (including registration) through my Sinatra-based API by using Warden.
What is the best way to do that? Or maybe I can use something different then Warden?
Keep in mind that I am not very familiar with Rack :)
I was able to get it working. There were a few main aspects:
Get Devise working with Rails (Devise is a Rails app, won't work
without it)
Setup the mapping (route) on Rack level to support both Rails and Sinatra
Share the sessions between Rails and Sinatra
Setup Warden and make it available to Sinatra
Here is most relevant part of code from /config.ru:
#
# ...
# Rest with Rails
map "/" do
run MyApp::Application
end
# Anything urls starting with /slim will go to Sinatra
map "/slim" do
# make sure :key and :secret be in-sync with initializers/secret_store.rb initializers/secret_token.rb
use Rack::Session::Cookie, :key => '<< see, initializers/secret_store.rb >>', :secret => '<< copy from initializers/secret_token.rb >>'
# Point Warden to the Sinatra App
use Warden::Manager do |manager|
manager.failure_app = AppMain
manager.default_scope = Devise.default_scope
end
# Borrowed from https://gist.github.com/217362
Warden::Manager.before_failure do |env, opts|
env['REQUEST_METHOD'] = "POST"
end
run AppMain
end
See, http://labnote.beedesk.com/sinatra-warden-rails-devise for a complete solution.
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'.