Skip to content

Instantly share code, notes, and snippets.

@andrewfritz86
Last active August 29, 2015 14:07
Show Gist options
  • Save andrewfritz86/0bde34e58a8ec2925c8f to your computer and use it in GitHub Desktop.
Save andrewfritz86/0bde34e58a8ec2925c8f to your computer and use it in GitHub Desktop.
Thoughts on Auth in our app

#Authentication, Logging in and Authorization in our app so far

###Authentication

Authentication in our app is fairly straightforward, at this point. In our gemfile, we require the gem 'bcrypt', and in our User model, we include the method has secure password. This tells the gem to look at the users table for the password_digest column that we need for the 'salted' or encoded version of our password.

We ask a user to input a password when they create their account. They also must input a confirmation for their password. Bcrypt looks at the password and password confirmation params, and if they match, it encodes the password into an enormous string of symbols and letters, (this is based off an algorithm, and it is equal to the password originally input). The original password isn't stored anywhere. When a user logs in, Bcrypt checks the database to make sure the encoded version of what the user enters upon login matches what's on the able. If that's the case, they are authenticated and logged in.

###What does 'logged in' actually mean to us?

To understand the concept of logging in to our app, we have to understand the concept of sessions first. A session is a temporary hash that a user 'carries' throughout their visit to the site. This hash disappears once they leave the site or close the browser; their session has ended.

In our app, logging in really just means having a user_id key and value set in the sessions hash. However, we don't set that key and value until we have done two things: look up the user to see if they exist in the database, and check that their password is correct.

Conversely, a user 'logs out' by clicking a link that simply sets the user_id key in their session to nil, or deletes the key entirely.

###Authorization

Authorization is a tricky concept, and it's going to be important for our app to be considered MVP.

At this stage, we are using essentially the same methods that PJ wrote yesterday to ensure that users can only view their own information, and not 'cheat the routes', so to speak. Their are a handful of methods, in the application_controller and and users_controller that we use to accomplish this.

In our application_controller, we've defined two methods, current_user and logged_in?

These two methods are in our application controller because we are presumably going to be calling them frequently, and in many different controllers.

######current_user

    def current_user
      @current_user ||= User.find_by(id: session[:user_id])
    end

This method simply sets the current_user to the 'current user' from session, buy only if it hasn't already been established.

######logged_in?

    def logged_in?
      current_user.present?
    end

This method simply checks that the current_user (already established in the above method), is actually logged in, and not nil.

Our users_controller contains three more private methods to control how we authorize users on our site (so far)

######load_user

    def load_user
      @user = User.find(params[:id])
      redirect_to root_path if !@user
    end

load_user is a method that establishes what user is being accessed based of the URL in the browser (hence the reference to params)

The key thing to understand here is that the user being accessed through params is NOT necessarily that user! ANYONE can type that route into the browser and attempt to access the information there!

######authenticate

    def authenticate
      redirect_to root_path if !logged_in?    
    end

authenticate simply checks that the logged_in method is returning true, and redirects the user back home if it's not. This prevents users that haven't logged in at all from randomly accessing routes.

######authorize

    def authorize

      if current_user != @user #here we are making sure that the user coming from params is the same as the user in params
      redirect_to user_path(current_user)
      end

    end

This method checks that the current_user (the user that is logged in, determined by session), is the same as the @user that we loaded earlier (which was based off params). If they aren't the same, the user is bounced back to their own show route, and never sees the route they were attempting to access.

#######before_action

The users_controller also uses a few before_actions to control what happens before a user can view any route under the users controller

before_action :load_user, only: [:show, :edit, :destroy, :update,]
before_action :authenticate, :authorize

Finally, if we look at our show action, we can see that the @user is simply established as the user from params in the erb rendered henceforth. However, the browser will never hit that action if they are bounced away from the action by one of the redirects included in the methods in before_action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment