Closed johannesschobel closed 1 year ago
3 options… 1 - add a type to the user and customize the flow 2 - if it’s just the email set it as a cookie. 3 - create a guest model, and add a guest attribute to Current.rb, load it from cookies in a before_action…
Dear @lazaronixon ,
i am not sure, if i explained it correctly. Actually, i don't want some kind of Guest
user (that can be "converted" into a real user, if the user signs up; as described in #75 ).
I want:
accessible
for everyone (i.e., logged in users, as well as users that are not currently logged in)Current.user
, if the user has been
logged in (before he moved to the page, i.e., if a cookie is set)I guess, we could have another method, like get_session
in the application_controller
in order to address this issue:
# ApplicationController
before_action :get_session
def get_session
return unless session_record = Session.find_by_id(cookies.signed[:session_token])
Current.session = session_record
end
This way, the Current.user
would work (if the user is logged in).
What do you think about this solution?
All the best, Johannes
I think you could figure out if the same user is looking at two different URLs, but not which user is. That is separate and distinct from your authentication system, which is where current_user
usually comes from, and has the responsibility for working out who you are dealing with, based on a shared secret like a username/password combo.
Everyone who interacts with a Web site (not Rails, I mean just any Web site served by any HTTP server) has a session. Rails helpfully exposes that server-side mechanism to you in the controller method session
. You can write any key you want into that on one request and read it back out on another. By that key, you can identify an anonymous user from one page to another. You can't know anything about them that you didn't put into that session yourself. And if they move to a different device, or restart their computer, or even wait around long enough before returning, you cannot know that they are a returning user.
https://guides.rubyonrails.org/v7.1.0/action_controller_overview.html#session
The next step up from a session is a cookie. Those come in two flavors: temporary and permanent*. You have to set any values to them in your application, and again, Rails makes that pretty simple to do within a controller method. If you set a "permanent" cookie in one request/response loop, you can read it on the next, and be reasonably certain you have the same visitor (or at least their browser on a single device) between those two visits. This value will survive a restart of the browser or machine, but will not travel between devices, or even different browsers on the same device. The user can also erase this value at their whim, as it is stored on their computer. There's only ~56K of space in a cookie (may be more, haven't actually looked at the spec in a long time) so usually what you stash there is a key, and then any larger data you want to access about the cookie's owner is kept in your database, identified by that key.
https://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
The CurrentAttributes mechanism does not do anything to keep track of the user for you. What it allows you to do is create cross-channels between the layers of a Rails application, such that your controllers (which are at the front line and have direct access to the Web server's session/cookie apparatus) can note the "current" information in a place where the models (which do not have any direct connection to an individual request) can read that and use it within their methods. All it does is give you a tidy way to refer to request-level information without passing that argument along in every method signature. It's still up to your application to put whatever information you want to be available at other layers of your application in there in the first place.
Most importantly: CurrentAttributes only sets these values for the duration of a single request/response loop. Anything you put in there on one page visit is gone after your server replies to that visit, and your application is responsible for setting it again during the next interaction.
https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
Walter
*Nothing can be set to last forever, but you can give it a significant time to live, up to 20 years. Temporary cookies are similar to sessions in terms of how your application interacts with them. They differ only in where the data is stored.
On Oct 5, 2023, at 2:36 AM, Johannes Schobel @.***> wrote:
Dear @lazaronixon ,
i am not sure, if i explained it correctly. Actually, i don't want some kind of Guest user (that can be "converted" into a real user, if the user signs up; as described in #75 ).
I want:
• to make a controller accessible for everyone (i.e., logged in users, as well as users that are not currently logged in) • still get the Current.user, if the user has been logged in (before he moved to the page, i.e., if a cookie is set) I guess, we could have another method, like get_session in the application_controller in order to address this issue:
ApplicationController
before_action :get_session
def get_session
return unless session_record = Session.find_by_id(cookies.signed[:session_token])
Current.session = session_record end This way, the Current.user would work (if the user is logged in). What do you think about this solution?
All the best, Johannes
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.
Dear @walterdavis ,
thank you very much for your extensive explanation and answer on this topic.
I think, having such a set_session
method, as described above, solves my issue.
All the best, Johannes
im surprised that it's not just me realize this issue @johannesschobel
when we work with another auth gem(read: devise) we can add <% if user_signed_in? %>
tag(cmiiw) to the navbar section, but i've just notice that this gem basically built based on 37signals's HEY influence
then why this important? if you put bit more attention, you'll notice that HEY has 2 domains, www.hey.com
ONLY FOR MARKETING and app.hey.com
ONLY FOR MAIN SERVICE
with these 2 purpose, we know that authentication on app.hey.com
trying to ISOLATE ENTIRE APP FROM PUBLIC EXPOSE rather than what rails programmer usually do
so if anyone plan to do something like in e-commerce site case, i suggest to add new line on main app controller to set session which can help to check if user already logged in or not
Dear @lazaronixon ,
thanks again for this wonderful gem. I have been playing around a bit, and i really like it. Following up on #81 , i have another question - maybe you could help and point me into the right direction?
In my application layout, i have a navbar that shows the email-address of the currently logged in user (i.e.,
Current.user.email
). This navbar is present in all views.Normal pages (i.e., everything related to
imprint
,about
,contact
, ...) should be accessible for "guest" users, therefore i have theskip_before_action :authenticate
in myPagesController
. However, when calling thepages#contact
route, theCurrent.user.email
is not shown, becauseCurrent.user
is not present. This is, because theauthenticate
method is not called (i.e., i use theskip_before_action
)How can i still get the
Current.user
, if the user has been logged in before?Thank you very much for helping me out. All the best, Johannes