Timeout for authentication_token only, not for database authenticable - ruby-on-rails-3

In config/initializers/devise.rb file,
config.timeout_in = 30.minutes
But this affects both users logging from browser and also, resets auth_token I think. But, I need to reset auth_token only after a small amount of time. How to do that?

You can control the behavior of the token timeout through creating a class method called expire_auth_token_on_timeout in your User model. If this method is set devise will reset the token upon timeout (alongside the user session). (This is defined in timeoutable.rb)
Now if you want to expire the auth token sooner than that you can just hook into the same warden hook and check this yourself and call record.reset_authentication_token! yourself.
The callback in question is after_set_user as described in the warden wiki
But you have to think about how you go about this and maybe create a seperate timestamp in your model that logs the last auth-token access to make sure you expire it after a certain amount of time. (You should also be able to determine if the request is a token request through the request object - keep in mind you are at the rack level, thus you can access the request through the env object).
I am sorry I can't provide any sample code for this, but you'll have to play around with the implementation and I don't have a test-case handy.

Related

Ember.js Authentication Token for Ember-Data + AMS => JSON or HTTP Header?

CONTEXT:
I have an Ember.js 1.1.0-beta.1 application that exchanges JSON data with a Rails-API server (Rails 4). JSON data exchange is accomplished with Ember-Data 1.0.0-beta.2 and Active Model Serializers 0.8.1 (AMS). I'm using the default recommended configurations for both Ember-Data and AMS, and am compliant with the JSON-API spec.
On any given RESTful call, the client passes the current authentication token to the server. The authentication token is verified and retired, and a new authentication token is generated and sent back to the client. Thus, every RESTful call accepts an authentication token in the request, and provides a new authentication token in the response that the client can cache and use for the next RESTful call.
QUESTION:
Where do I put the authentication token in each request and response?
Should it be part of each object's JSON in request and response? If so, where is the token placed in the existing object's JSON structure (which has nothing to do with authentication)?
Or should they be placed in the HTTP header for each request and response object?
What is "The Ember Way" that one might eventually expect to find in the new Ember Guides Cookbook?
MORE CONTEXT:
I'm already familiar with the following links:
#machty 2 Embercasts: http://www.embercasts.com/episodes/client-side-authentication-part-2
#wycats tweet: https://twitter.com/wycats/status/376495062709854209
#cavneb 3 blog posts: http://coderberry.me/blog/2013/07/08/authentication-with-emberjs-part-1
#simplabs blog post: http://log.simplabs.com/post/53016599611/authentication-in-ember-js
...and am looking for answers that go beyond these, and are specific to Ember-Data + AMS.
With the exception of the need to pass a new token back to the client in the response via Ember-Data, assume my client code is otherwise similar to the #machty Embercast example on GitHub: https://github.com/embercasts/authentication-part-2/blob/master/public/js/app.js
Thank you very much!
I've got a similar stack - ember, ember-data and rails-api with AMS. Right now, I'm just passing the authentication token (which I store in localStorage) in a header (though you could pass it on the query string) by modifying the RESTAdapter's ajax method.
My initial thought would be to avoid resetting the token on every request. If you're particularly concerned about the token being sniffed, it might be easier to just reset the token on the server at a regular interval (say, 10 minutes). Then, if any request from the client fails due to an old token, just fetch the new token (by passing a'reset token' that your server gives you at login) and replay the initial request.
As for where to put the token, there isn't really an "Ember Way" - I prefer passing it in a header since passing it in the query string can mess with caching and is also more likely to be logged somewhere along the way. I'd definitely avoid passing it in the request body - that would go against what ember-data expects, I'd imagine.
I have built something similar, although I do not reset the token unless the user signs out.
I would not put it in the request body itself - you are just going to pollute your models. There probably is no Ember way since this is more of a transport issue. I pass the token using a custom HTTP header and/or a cookie. The cookie is needed to authorize file downloads, which can not be done through ajax, although the cookie works for ajax calls too. In your case I would use a cookie and have the server set it to the new value each time. However, your scheme of resetting the token on each JSON request is not going to work on simultaneous requests. Is this really necessary? If you use TLS you probably don't need to worry so much. You could also timeout the token so that if there are no requests for 10 minutes a new token is generated.

RestKit how to check for wrong username or password error

I want to be able to notify the user if he entered the wrong username/password, or if for example the database is down. I am not sure if I need to do it in the didLoadResponse and just check that the response is not isOK or in the didFailLoadWithError.
Thanks
How you handle it depends on how you perform a login.
If you do basic authentication, by passing the username and password in the header of the request, then you'll get an error back from the service you're calling. And your delegate method, "objectLoader:didFailWithError:" method will get called. This method will most likely get called if there's a catastrophic problem on the backend, like the database being down.
If you have a separate webservice that performs a login operation, then it probably sends back a valid block, indicating whether the user-pass was valid or not. In this case, your "objectLoader:didLoadObject:" method probably got called, and you'll have to decipher the result appropriately.
Keep in mind that this behavior is totally controlled by what the back-end services do. If you can't talk directly with the people working on the services, then this may just be trial-and-error, and until you discover how those services work.

is possible to keep session alive using NSURLConnection doing different requests?

I am using NSRULConnection to make http request on my iphone application. All works just fine.
The problem is after logged in I need to keep the same session to get data from the server.
I read a few posts saying all I need was using the same instance of NSURLConnection and it would use the same session... if that is true, that doesn't make sense to me, cause the NSURLConnection is not mutable and there is no method to change the request since I have to access different pages.
Is there anyway simple way to keep a session using NSURLConnection.
If you are managing sessions using cookies, there is no need to do anything special to achieve session management.The URL loading system automatically sends any stored cookies appropriate for an NSURLRequest. unless the request specifies not to send cookies. So, your sessions should be managed automatically for you.
However, as the Apple's doc says, if someone has set the cookie-acceptance policy to reject all cookies or only accept cookies selectively, you might be in a fix (you can change the cookie acceptance policy yourself too). In such a case, you might resort to URL based session-management; in which you append a session-identifier to the URL as a parameter (You can get this identifier as a part of the successful log-in response), which can be extracted on the server-side. This, however, is considered really bad practice.
Another way, which I have come across more often, is to get a session-identifier as part of the response for a successful log-in and include that identifier in all your subsequent requests as a parameter. Although this would require a major change in the way the server handles the sessions.

How to access current_user from a Rails Notification?

I'm building an audit trail that needs to know which user is currently making the request. My audit trail is built using ActiveSupport::Notifications to receive an even that needs to be audited.
What I would like to do is use an ActiveSupport::Concern to encapsulate the logic for my audit needs, so that I can easily add auditing to any model in my system.
In general this is easy to do. I even blogged about it a while back. However, I'm having a hard time figuring out how to get the current user that making the request to the web server, so that I can log who is making what changes in my audit trail.
I know there are a ton of questions about "how do I get current_user in my model" but I'm not asking about doing it in a model, so I'm hoping there is a better set of answers. Since my audit code is infrastructure related, I am hoping that there is some way I can tap into the current request that is being processed, or something else that would definitively tell me who is currently logged in / making the request.
I've read a lot of "answers" that say to use thread storage and put the current_user in there. I don't like this answer for many of the reasons that others don't - there is no guarantee that thread storage is safe. it could bleed across multiple requests if the server uses the same thread to process multiple requests, etc.
so... given that I am not trying to access current_user from my model, but rather from either an ActiveSupport::Concern or ActiveSupport::Notifications event subscription, are there any good options for me to know who the current user is?
Update
I'm using devise for authentication, which uses Warden on the back end. devise retrieves the current_user by calling request.env['warden'].authenticate(:scope => :user) (assuming i use a "User" model for authentication).
Is there a way for me to access the current request object from within my concern or notification subscription? Back in my .NET days, I would have been able to call HttpContext.Current.Request and all would be good. What's the equivalent in Rails?
Rails' ActionController::Instrumentation has explicit support for this, using append_info_to_payload.
Add a method to your ApplicationController:
def append_info_to_payload(payload)
super
payload[:current_user_id] = current_user.try(&:id)
end
now, when your observer is called back, the information will be in the event.payload:
ActiveSupport::Notifications.subscribe /process_action.action_controller/ do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
current_user_id = event.payload[:current_user_id]
# do something interesting with current_user_id here
end
You already have the answer, what you're doing is the same as when people are accessing the request in models. The current_user is just a method defined on your ApplicationController. When you're not in a controller or other class that inherits from it, you can't access that method.
HttpContext.Current.Request << I would bet a lot that this uses thread storage. Any other solution we find will also be thread storage at some level or another.
Either pull out what you need from the request in the controller and pass it down as parameters, or use thread storage -- but this is inherently dangerous anyway. What if you start using delayed job to do the notifications or something?

Securely storing variables without session in zope

I want to store values in variables to access form another page (a.k.a State management).
Now I cannot use sessions since I have multiple Zope instances & if one fails the user need to be redirected to another Zope instance and one session is valid only for one Zope instance.
Now my remaining options are
submit a Hidden input tag using POST method
Passing through URL with GET method
Using cookies
Using Database (which I think is 'making simple things complex'.)
I am not even considering the first 2 methods and I think using cookies is not secure.
So is there a commercial or open source module that can securely (encryption etc.) do cookie management.
If not I will have to use a database.
Please inform me, if I am missing something.
Version - Zope 2.11.1
The SESSION support built-in to Zope 2 actually keeps the session in a temporary partition of the ZODB so I think it actually is valid for multiple Zope clients connecting to the same ZEO server. The cost of this is that all session changes invoke the transaction machinery and result in a commit, so just make sure you're not using the SESSION in something very low-level like PAS auth or you'll have commits hitting your ZODB for every image, CSS file, and JS file.