Git Product home page Git Product logo

rails-blog-sessions's Introduction

Rails Blog: Authentication from Scratch using Sessions

This is the fifth iteration of our Blog App.

We built out a user model a while back, but we haven't been doing much with it yet. Let's build out a signup and login system that prevents a user from writing a blog post or a comment without logging in. For now, we're going to build our own log in system using sessions.

Before anything, note that when you generate models, controllers, etc, be sure to include this option, so that it skips tests (which we already have): --no-test-framework

Signing up

  1. Create a new migration for our users table that makes the following columns: email and password_digest (both strings). Create a validation on email presence and uniqueness on the user model.
  2. Add the 'bcrypt' gem to our Gemfile to use the Active Record has_secure_password method, which adds methods to set and authenticate against BCrypt passwords. We don't need to create validations for password presence, because it's included within this method.
  3. Now we have password and password_confirmation attributes (which we can permit in params on the users controller). Note that these aren't columns on our database, but attributes handled by the bcrypt gem.
  4. Let's fix our routes to have a route for signup that points to the "new" method on our users controller.
  5. On the create method in the users controller, point a successful sign up to a root_path (posts index page) that we'll make in our routes file.
  6. Update our form for creating a new user to include email, password, and password confirmation. The passwords should have a password_field input.
  7. Let's also build out a _header partial that we render in application.html.erb that will have a Sign Up link, and other helpful navigation links.

Logging in with Sessions

Now that we have our sign up process built out, we can expand it into a log in system. A user who is signed up should be able to log in to see certain pages. We'll be using sessions, which allow an application to keep track of a user and allow them to perform actions that are remembered by the application without authenticating on every request. A session is comprised of a hash of values, usually a user's id and other information, as well as a session id. Learn more from the documentation on sessions in rails.

  1. Generate a Sessions controller. We'll make the views later.
  2. Our sessions controller will handle two actions, creating a new session and destroying it. A new session is generated when a user logs in or signs up (which is handled on the users controller by the create method.
  3. In the create method, you will need to find a user by their email and authenticate it (calling .authenticate) on the password from params. Then assign the session[:user_id] to the user.id. Check out this blog post on authentication for more info.
  4. Build out the appropriate routes for these actions, and include a resource for sessions.
  5. Add to your _header nav links for logging out and logging in, and render a form as a form_tag for logging in under sessions (make it a partial and render it in a new view); it should post to the sessions_path.
  6. Now we can associate submitting a post and comment with a user via the session["user_id"]. Include a hidden_field tag on both forms to handle that association. Now refactor the show pages to display the user for comments and posts.

Signing up with Sessions

  1. Make sure that when a new user signs up, their session is stored as well. You can handle this by setting the session id with the user id when creating a new user.

Authenticating with Sessions

Now that we have sessions, we can create conditionals on various actions in our app. Let's make it that a user must be logged in to post a post or submit a comment.

  1. In the application controller, make a private helper_method called current_user that will find a user by their session id and assign to an instance variable @current_user.
  2. Make another helper method user_signed_in? that checks for a session user_id and returns true or false
  3. Let's also make a method authorize that renders our login page if a !user_signed_in?. We're going to call this method as a before_action on our comments and posts controllers that will run this check before the edit, update, create, new, and destroy methods.
  4. This will help us in our header to render info about the logged in user, and create some view logic to only render a logout link and new post link if the user is logged in. Have the current user's name displayed too to let them know they're logged in.
  5. Refactor our forms that handle new comments to check if the user is signed in.
  6. Use the tests to guide how to build out this view logic.

Pass all of the integration tests.

Resources

'bcrypt' gem

has_secure_password method

sessions in rails

authentication

before_action

View Rails Blog: Authentication from Scratch using Sessions on Learn.co and start learning to code for free.

rails-blog-sessions's People

Contributors

ahimmelstoss avatar deniznida avatar fislabstest avatar fs-lms-test-bot avatar irmiller22 avatar roseweixel avatar sarogers avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

tylerbrewer2

rails-blog-sessions's Issues

Awesome lab. Two things I noticed.

I really liked this lab. I haven't peeped the solutions yet to review everything I got wrong. But I did notice two things:

ONE In spec/login_helper.rb, Capybara looks for buttons in two different ways. In lines 6, 7, 17, and 18 the spec uses fill_in(:symbol, :with ...):

6    fill_in(:email, :with => @crookshanks.email)
7    fill_in(:password, :with => @crookshanks.password)

17    fill_in(:email, :with => "Not")
18    fill_in(:password, :with => "signed up")

But then in lines 28 - 31 and 42 - 45, it uses fill_in("String", :with...):

28    fill_in("Name", :with => @kitten.name)
29    fill_in("Email", :with => @kitten.email)
30    fill_in("Password", :with => @kitten.password)
31    fill_in("Password confirmation", :with => @kitten.password_confirmation)

The first way forces awkwardness like this to be used (otherwise Capybara will not find the button which would otherwise be automatically generated with a capital 'E'):

  <div class="field">
    <%= f.label :email, "email" %><br>
    ...

The second style seems cool though! Maybe they are both present on purpose. Just pointing that out.

TWO All my tests are passing but I didn't need to write anything to ensure that only the same user who posted a blog or a comment is able to edit or delete that post or comment. Basically anyone who logs in can do anything, and that's cool with the spec.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.