👨🏿‍💻
Learn
  • Learn And The Power Of Community
  • Intro
    • learn-co-curriculum/welcome-to-learn-verified
    • learn-co-curriculum/your-first-lab
    • learn-co-curriculum/environment-setup
  • Intro to tic tac toe
    • matz-readme
    • what-is-a-program?
    • hello world
    • Intro to irb
    • Reading-error-messages
    • Data-types
    • variable
    • Variable-assignment lab
    • String interpolation
    • Interpolation-super-power
    • Welcome to tic tac toe
    • Array
    • Tic tac toe board
    • Intro to methods
    • Puts print and return
    • Intro-to-tdd-rspec-and-learn
    • Methods and arguments
    • Say hello (lab)
    • Methods-default-arguments
    • ttt-3-display_board-example
    • ttt-4-display-board-rb
    • Intro-to-cli-applications
    • Greeting-cli
    • cli-applications in Ruby
    • Ruby-gets-input
    • Tic tac toe move
    • Truthiness-in-ruby-readme
    • booleans
    • conditional (if)
    • ttt-6-position-taken
    • ttt-7-valid-move
    • rspec-fizzbuzz
    • Looping-introduction
    • Loop
    • while-and-until-loop
    • Tic Tac Toe Turn lab
    • looping-while-until lab
    • Tic Tac Toe Play Loop (lab)
    • Tic Tac Toe Current Player (lab)
    • Intro to ruby iterators
    • Nested Arrays
    • Boolean Enumerators
    • Search Enumerators
    • Tic Tac Toe Game Status
    • tic-tac-toe
  • OOP tic tac toe
    • intro to oop
    • Intro-to-classes-and-instances
    • Classes-and-instances-lab
    • Instance-methods
    • Instance-methods-lab
    • Object Attributes
    • object-attributes-lab
    • Object Initialization
    • Object-initialize-lab
    • oop barking dog lab
    • Procedural-vs-oop
    • oop tic tac toe
  • Git and github
    • Intro to Version Control
    • Git Repository Basics
    • Git-basics-quiz
    • Forks-and-clones
    • Git Remotes and Github
    • Git Remotes and Github Codealong
    • Thinking Ahead: GitHub as Career Differentiator
    • Github Pull Requests
    • Git Collaboration
    • Git-collaboration-quiz
    • Git Basics Quiz
  • HTML
    • A-quick-tour-of-the-web
    • The-web-is-made-of-strings
    • What-makes-the-web-possible?
    • html-introduction
    • Your first-html-tag-lab
    • Nested-tags-and-attributes
    • Well-formed-html-document-lab
    • HTML elements types overview
    • Researching-HTML-elements
    • Separation-of-content-and-presentation
  • CSS
    • Introduction-to-css
    • introduction-to-css-code-along
  • Procedural Ruby
    • Regex-what-is-a-pattern
    • Regex-basics
    • Regex-lab
    • Regex-match-scan-grep-methods
    • learn-co-curriculum/method-arguments-lab
    • Method-scope
    • Return Values Lab
    • Debugging-with-pry
    • Method-scope-lab
    • Truthiness-code-challenge
    • If Statements Lab
    • Case-statements
    • Case-statements-quiz
    • Logic and Conditionals Quiz
    • Ternary Operators and Statement Modifiers lab
    • Looping Lab
    • looping-quiz
    • learn-co-curriculum/looping-times
    • countdown-to-midnight lab
    • Array introduction
    • Using Arrays
    • Array-CRUD-lab
    • Array-methods
    • Array-methods-lab
    • Square array lab
    • Collect and Return Values
    • Collect Lab
    • Badges and Schedules Lab
    • Oxford comma lab
    • Deli counter lab
    • Reverse Each Word Lab
    • Yield-and-blocks
    • Each Lab
    • Return from Yield Statements
    • My All? Lab
    • My Find Lab
    • Cartoon Collections Lab
    • Enumerators Code Challenge
    • Prime? Lab
    • Sorting
    • Sorting Lab
    • Introduction to Hashes
    • Using Hashes lab
    • Ruby-symbols
    • Hash iteration
    • Hash Iteration Lab
    • Hash Iteration with Collect
    • Intro to Nested Hashes
    • Building Nested Hashes
    • Building Nested Hashes Lab
    • Nested Hash Iteration
    • Nested Hashes Lab
    • Multitype Collections Lab
    • Iterating over Nested Hashes Codealong
    • Other Hashes Codealong
    • Hashes Manipulation Lab
  • OOP Ruby
    • OO Ruby Video: Object Orientation Overview
    • Object Accessors
    • Instance Variables lab
    • Video Review: Object Properties
    • Meowing Cat
    • Intro to Object Orientation - Ruby
    • oo basics lab
    • OO Basics with Class Constants
    • Self
    • OO School Domain lab
    • OO Counting Sentences lab
    • Class Variables and Methods
    • Class Variables and Methods Lab
    • Remembering Objects
    • Puppy Lab
    • Advanced Class Methods
    • Advanced Class Methods Lab
    • Video Review: Object Models
    • OO Email Parser lab
    • OO Anagram Detector lab
    • OO Cash Register lab
    • Intro to Object Relationships
    • Belongs to Object Lab
    • Has Many Object
    • Has Many Object Lab
    • Collaborating Objects Review
    • Collaborating Objects Lab
    • OO My Pets
    • oo kickstarter lab
    • OO Banking lab
    • Has Many Objects Through
    • Has Many Objects Through Lab
    • Intro to Inheritance
    • Intro to Inheritance Lab
    • Super
    • Super Lab
    • Intro to Modules
    • Intro to Modules Lab
    • Mass Assignment
    • Mass Assignment and Metaprogramming
    • Mass Assignment Lab
    • Custom Errors lab
    • OO Triangle lab
  • Scraping and project
    • Gems and Bundler
    • Scraping
    • Scraping Lab
    • Kickstarter Scraping Lab
    • Video Review: Object Orientation and Scraping
    • OO Ruby Object Orientation Video Review
    • Music Library CLI
    • Video Review: Music Library CLI
    • Tic-tac-toe with AI project
    • Student Scraper
    • CLI Data Gem Portfolio Project
    • CLI Data Gem Walkthrough
    • CLI Data Gem Walkthrough: Creating a CLI Scraper Gem
    • Common Anti-Patterns in CLI Data Gem
    • Student Example 1: Refactoring CLI Gem
    • Student Example 2: Refactoring CLI Gem
  • SQL
    • What is SQL
    • SQL Intro and Installation
    • SQL Database Basics
    • SQL Databases and Text Editors
    • SQL Data Types
    • SQL Inserting, Updating, and Selecting
    • Basic SQL Queries
    • SQL Aggregate Functions
    • SQL Aggregate Functions Lab
    • SQL Bear Organizer Lab
    • Edgar Codd and Table Relations
    • Table Relations
    • SQL JOINS
    • SQL Complex Joins
    • SQL Join Tables
    • Grouping and Sorting Data
    • SQL Joins Review Lectures
    • SQL Crowdfunding Lab
    • SQL Library Lab
    • Pokemon Scraper Lab
  • ORM And Active record
    • Why an ORM is Useful
    • Mapping Ruby Classes to Database Tables
    • Mapping Classes to Tables Lab
    • Mapping Database Tables to Ruby Objects
    • Mapping Database Rows to Objects Lab
    • Updating Records in an ORM
    • Updating Records in an ORM Lab
    • Preventing Record Duplication
    • ORMs Lab: Bringing It All Together lab
    • Dynamic ORMs
    • Dynamic ORMs with Inheritance
    • ActiveRecord Mechanics
    • Translating from ORM to ActiveRecord
    • Intro to Rake
    • Mechanics of Migrations
    • Writing Our Own Migrations
    • Migrations and Active Record Lab
    • ActiveRecord CRUD Lab
    • Advanced Finding Lab
    • ActiveRecord Associations
    • ActiveRecord Associations Lab
    • ActiveRecord Associations Lab II
    • ActiveRecord Associations Video Review
    • ActiveRecord Associations Video Review II
    • Video Review: Aliasing ActiveRecord Associations
    • Video Review: Blog CLI with ActiveRecord and Associations
  • Rack
    • How the Internet Works
    • Increasing Layers of Abstraction
    • Inspecting the Web with Rack (lab)
    • The HTTP Request
    • Dynamic URL Routes
    • Dynamic Web Apps with Rack (lab)
    • Rack Responses Lab
    • Rack Routes and GET Params Lab
    • HTTP Status Codes
    • Dynamic URLs and Status Codes Lab
    • Video Review: How The Web Works, Pt 1
    • Video Review: How the Web Works, Pt 2
  • Html
    • How the Web Works
    • Site Planning
    • HTML Fundamentals
    • HTTP Status Codes
    • video review how the web works pt 1
    • How the Web Works, Part 2: Overview
    • Setting Up a New Site
    • Document Structure
    • Text Formatting
    • HTML Tables
    • Html-images
    • HTML Links
    • Html backing-up changes
    • HTML Validation
    • Quiz - HTML Fundamentals
    • Dev Tools Super Power
    • HTML Lists
    • Html issue bot 9000 (lab)
    • HTML Forms and Iframes
    • HTML Map and Contact Form Code-along
    • HTML5 Media
    • HTML5 Video Embed Code-Along
    • HTML5 Semantic Elements
    • HTML5 Semantic Containers Code-along
    • HTML5 Quiz
  • CSS
    • CSS Fundamentals
    • CSS Styling Code Along
    • My Little Rainbow
    • CSS Kitten Wheelbarrow
    • CSS Graffiti Override Lab
    • CSS Issue Bot 9000
    • Your first deployment
    • The Box Model
    • Layout Types
    • Float
    • Clearfix
    • Centering
    • Column Structure
    • CSS Columns Code Along Exercise (lab)
    • Box Model & Page Layout
    • Using Z Index
    • Positioning
    • ZHW Shoes Layout (lab)
    • Zetsy (lab)
    • CSS Box Style Code Along
    • Animal Save (lab)
    • Building Responsive Sites
    • Intro to Responsive Media
    • CSS Media Queries
    • Working with Responsive Type
    • Responsive layout
    • The Viewport Property
    • Responsive Features Code-Along (lab)
    • Bootstrap Introduction
    • Bootstrap Code-Along
    • Bootstrap Grid System
    • Grid Layout Code-Along
    • Bootstrap Navbar Code-Along
  • Sinatra
    • What is Sinatra?
    • Sinatra From Scratch
    • Using the Shotgun Development Server (lab)
    • Sinatra Basics
    • Sinatra Hello World Basics (lab)
    • Routes in Sinatra
    • Sinatra Routes Lab
    • Intro To MVC
    • Sinatra MVC File Structure (lab)
    • Sinatra Views: Using ERB
    • Sinatra Views (lab)
    • Sinatra Basic Views Lab
    • Sinatra Views Lab II
    • Intro To Capybara
    • Dynamic Routes in Sinatra
    • HTML Forms and Params
    • Passing Data Between Views and Controllers in Sinatra
    • Sinatra Forms Lab
    • Sinatra Yield Readme
    • Integrating Models Sinatra Code-along
    • Sinatra MVC Lab - Pig Latinizer
    • Sinatra Basic Forms Lab
    • Sinatra Forms
    • Nested Forms Readme
    • Sinatra Nested Forms Lab: Pirates!
    • Lab Review-- Sinatra Nested Forms Lab: Pirates
    • Sinatra Nested Forms Lab: Superheroes!
    • Sessions and Cookies
    • Mechanics of Sessions
    • Sinatra Basic Sessions Lab
    • Using Sessions
    • Sinatra and Active Record CRUD
    • Sinatra Activerecord Setup
    • Sinatra ActiveRecord CRUD
    • User Authentication in Sinatra
    • Sinatra Sessions Lab - User Logins
    • Securing Passwords
    • Secure Password Lab
    • Sinatra Authentication- Overview
    • RESTful Routes
    • Restful Routes Basic Lab
    • Sinatra ActiveRecord Associations: Join Tables
    • Using Tux in Sinatra with ActiveRecord
    • ActiveRecord Associations in Sinatra
    • Sinatra Multiple Controllers
    • Sinatra and Active Record: Associations and Complex Forms
    • Sinatra Playlister (lab)
    • Welcome to NYC Sinatra! (lab)
    • Building a Site Generator, Part 1- Overview
    • Building a Site Generator, Part 2- Overview
    • Fwitter Group Project
  • Rails
    • Welcome To Rails
      • Rails Application Basics
      • Rails Static Request
      • Rails Hello World Lab
      • Rails Model View Controller
      • Intro to Rails- Overview
    • Intro to REST
    • Active Record Models and Rails
    • ActiveRecord Model Rails Lab
    • RESTful Index Action Lab
    • Rails Dynamic Request
    • Rails Dynamic Request Lab
    • Rails URL Helpers
    • Rails URL Helpers Lab
    • Rails form_tag
    • Rails form_tag Lab
    • Create Action
    • Create Action Lab
    • Index, Show, New, Create Lab
    • Edit/Update Action
    • form_for on Edit
    • Strong Params Basics
    • form_for Lab
    • Rails Generators
    • CRU with form_for Lab
    • Resource and Scaffold Generator
    • Rails Blog scaffold
    • Todo mvc assets and managing lists
    • Rails Forms Overview
    • ActiveRecord Validations
    • ActiveRecord Validations Lab
    • Validations in Controller Actions
    • Validations In Controller Actions Lab
    • Validations with form_tag
    • Validations with form_for
    • DELETE Forms and Requests
    • Testing in Rails
    • Validations with form_tag
    • CRUD With Validations Lab
    • Join the Fun rails
    • Activerecord lifecycle reading
    • Displaying Associations Rails
    • Active Record Associations Review
    • Forms And Basic Associations Rails
    • Forms And Basic Associations Rails Lab
    • Basic Nested Forms
    • Displaying Has Many Through Rails
    • Displaying Has Many Through Rails Lab
    • Has Many Through Forms Rails
    • Has Many Through Forms Rails Labs
    • Has Many Through in Forms Lab Review- Overview
    • Deep Dive into Nested Forms- Overview
    • Layouts And Templates in Rails
    • Rails Layouts And Templates Lab
    • Simple Partials
    • Simple Partials Lab
    • Partials with Locals
    • Partials with Locals
    • Refresher on MVC
    • Refactoring Views With Helpers
    • Refactoring Views With Helpers Lab
    • Model Class Methods
    • Optimal Queries using Active Record (lab)
    • Routing And Nested Resources
    • Nested Resource Routing Lab
    • Modifying Nested Resources
    • Modifying Nested Resources Lab
    • Namespaced Routes
    • Namespaced Routes Lab
    • Todomvc 2 lists have items
    • TodoMVC 3: Mark Items Complete
    • Todomvc 4 refactoring with partials and helpers
    • Todomvc 5 deleting items
    • Introduction to Authentication and Authorization
      • Cookies and sessions
      • Cookies and Sessions Lab
      • Sessions Controller
      • Sessions Controller Lab
      • Login Required Readme
      • Login Required Lab
      • Using has_secure_password
      • Has_secure_password lab
      • Authentication- Overviewn
      • OmniAuth
      • Omniauth Lab
      • Omniauth review lecture in todomvc
      • Authentication and authorization recap and gems
    • Rails Amusement Park lab
    • How to Find Gems
  • JavaScript
    • Intro to JavaScript
      • JavaScript Data Types
      • JavaScript Data Types Quiz
      • JavaScript Variables
      • JavaScript Comparisons
      • Conditionals
      • Logical Operators
      • Functions
      • Intro to Debugging
      • Intro to Testing
      • JavaScript Basics Quiz
    • Scope
      • Scope chain
      • JavaScript Practice Scope Lab
      • Lexical scoping
      • Errors and Stack Traces
      • Hoisting
    • Arrays And Objects
      • Objects
      • JavaScript: Objects and Arrays Quiz
      • Object Iteration
      • JavaScript Logging
      • Traversing Nested Objects
      • Filter
      • Map
    • Functions Revised
      • First-Class Functions Lab
      • First-Class Functions
      • First-Class Functions Practice
      • First-Class Functions Practice Lab
    • OOP
      • Creating Objects
      • Object Methods and Classes
      • Using Prototypes
      • Using Classes in Javascript
      • JavaScript This Walkthrough
      • This Code-along
      • Bind, Call, and Apply Readme
      • Bind, Call, Apply Lab
      • Object Relations
      • Association Methods in Javascript
      • Class Relations Lab
      • JavaScript Closures and Higher Order Functions
      • Closures Lab
      • JavaScript Arrow Functions
      • Daily Lunch Lab
    • DOM
      • Introduction to the DOM
      • Introduction to the DOM Lab
      • More on the DOM
      • Creating and Inserting DOM Nodes
      • The DOM Is a Tree
      • Listening to Nodes
      • Modify HTML With jQuery
      • Modifying HTML Lab
      • jQuery Selectors
      • Document.ready
      • Acting On Events Lab
      • DOM Quiz
    • Templates
      • Introduction to CSS
      • CSS Quiz
      • CSS Libraries
      • CSS Libraries Lab
      • Intro to Templates
      • Template Engines
      • Template Engines Lab
      • Advanced Templating
      • Advanced Templating Lab
    • Asynchronous JavaScript
      • Intro to XHR Code Along
      • Hitting APIs Lab
      • Advanced AJAX Lab
      • AJAX and Callbacks
      • AJAX and Callbacks Lab
      • REST Refresher
      • REST Quiz
      • Fetch
      • JavaScript fetch() Lab
      • Intro to Mocha
      • Testing with Spies
      • Testing with Mocks and Stubs
  • Rails and JavaScript
Powered by GitBook
On this page
  • Overview
  • Objectives
  • User Authorization: Using Sessions
  • Logging In
  • Logging Out
  • User Registration
  • Project Structure
  • Our Project
  • The app Folder
  • Part I: Models and Migrations
  • Part II: Controllers and Views
  • Conclusion
  1. Sinatra

User Authentication in Sinatra

Overview

In this codealong lab, we'll build a Sinatra application that will allow users to sign up for, log into, and then log out of your application.

Objectives

  1. Explain how logging in to an application stores a user's ID into a session hash

  2. Set up a root path and homepage for the application

  3. Build a user sign-up flow with a Users model that signs in and logs in a user

  4. Log out the user by clearing the session hash

User Authorization: Using Sessions

Logging In

What does it mean for a user to 'log in'? The action of logging in is the simple action of storing a user's ID in the session hash. Here's a basic user login flow:

  1. User visits the login page and fills out a form with their email and password. They hit 'submit' to POST that data to a controller route.

  2. That controller route accesses the user's email and password from the params hash. That info is used to find the appropriate user from the database with a line such as User.find_by(email: params[:email], password: params[:password]). Then, that user's ID is stored as the value of session[:user_id].

  3. As a result, we can introspect on the session hash in any other controller route and grab the current user by matching up a user ID with the value in session[:user_id]. That means that, for the duration of the session (i.e., the time between when someone logs in to and logs out of your app), the app will know who the current user is on every page.

A Note On Password Encryption

For the time being, we will simply store a user's password in the database in its raw form. However, that is not safe! In an upcoming lesson, we'll learn about password encryption: the act of scrambling a user's password into a super-secret code and storing a de-crypter that will be able to match up a plaintext password entered by a user with the encrypted version stored in a database.

Logging Out

What does it mean to log out? Conceptually, it means we are terminating the session, the period of interaction between a given user and our app. The action of 'logging out' is really just the action of clearing all of the data, including the user's ID, from the session hash. Luckily for us, there is already a Ruby method for emptying a hash: #clear.

User Registration

Before a user can sign in, they need to sign up! What does it mean to 'sign up'? A new user submits their information (for example, their name, email, and password) via a form. When that form gets submitted, a POST request is sent to a route defined in the controller. That route will have code that does the following:

  1. Gets the new user's name, email, and password from the params hash.

  2. Uses that info to create and save a new instance of User. For example: User.create(name: params[:name], email: params[:email], password: params[:password]).

  3. Signs the user in once they have completed the sign-up process. It would be annoying if you had to create a new account on a site and then sign in immediately afterwards. So, in the same controller route in which we create a new user, we set the session[:user_id] equal to the new user's ID, effectively logging them in.

  4. Finally, we redirect the user somewhere else, such as their personal homepage.

Project Structure

Our Project

Our file structure looks like this:

-app
  |- controllers
      |- application_controller.rb
  |- models
      |- user.rb
  |- views
      |- home.erb
      |- registrations
          |- signup.erb
      |- sessions
          |- login.erb
      |- users
          |- home.erb
-config
-db
-spec
...

The app Folder

The app folder contains the models, views and controllers that make up the core of our Sinatra application. Get used to seeing this setup. It is conventional to group these files under an app folder.

Application Controller

  • The get '/registrations/signup' route has one responsibility: render the sign-up form view. This view can be found in app/views/registrations/signup.erb. Notice we have separate view sub-folders to correspond to the different controller action groupings.

  • The post '/registrations' route is responsible for handling the POST request that is sent when a user hits 'submit' on the sign-up form. It will contain code that gets the new user's info from the params hash, creates a new user, signs them in, and then redirects them somewhere else.

  • The get '/sessions/login' route is responsible for rendering the login form.

  • The post '/sessions' route is responsible for receiving the POST request that gets sent when a user hits 'submit' on the login form. This route contains code that grabs the user's info from the params hash, looks to match that info against the existing entries in the user database, and, if a matching entry is found, signs the user in.

  • The get '/sessions/logout' route is responsible for logging the user out by clearing the session hash.

  • The get '/users/home' route is responsible for rendering the user's homepage view.

The models Folder

The models folder is pretty straightforward. It contains one file because we only have one model in this app: User.

The code in app/models/user.rb will be pretty basic. We'll validate some of the attributes of our user by writing code that makes sure no one can sign up without inputting their name, email, and password. More on this later.

The views Folder

This folder has a few sub-folders we want to take a look at. Since we have different controllers responsible for different functions/features, we want our views folder structure to match up.

  • The views/registrations sub-directory contains one file, the template for the new user sign-up form. That template will be rendered by the get '/registrations/signup' route in our controller. This form will POST to the post '/registrations' route in our controller.

  • The views/sessions sub-directory contains one file, the template for the login form. This template is rendered by the get '/sessions/login' route in the controller. The form on this page sends a POST request that is handled by the post '/sessions' route.

  • The views/users sub-directory contains one file, the template for the user's homepage. This page is rendered by the get '/users/home' route in the controller.

  • We also have a home.erb file in the top level of the views directory. This is the page rendered by the root route, get '/'.

Part I: Models and Migrations

Our User model has a few attributes: a name, email, and password.

Step 1: Migration

Write a migration that creates a Users table with columns for name, email, and password. Run rake db:migrate SINATRA_ENV=test and then run your test suite.

You'll see that you're passing a number of tests, including these:

User
  is invalid without a name
  is invalid without a email
  is invalid without an password

Part II: Controllers and Views

Step 1: The Root Path and the Homepage

First things first, let's set up our root path and homepage.

  • Open up app/controllers/application_controller.rb and check out the get '/' route. This route should render the app/views/home.erb page with the following code:

  • Run your test suite again with learn or rspec in the command line and you should be passing these two tests:

ApplicationController
  homepage: GET /
    responds with a 200 status code
    renders the homepage view, 'home.erb'
  • Let's look at the code behind this view. Open up app/views/home.erb and you should see the following:

<h1>Welcome to Hogwarts</h1>
  <h4>Please sign up or log in to access your @hogwarts.edu email account</h4>
  <a href="/registrations/signup">Sign Up</a>
  <a href="/sessions/login">Log In</a>

Notice that we have two links, the "Sign Up" link and the "Log In" link. Let's take a closer look:

  • The 'href' (destination) value of the first link is /registrations/signup. This means that the link points to the get '/registrations/signup' route.

  • The 'href' value of the second link is /sessions/login. This means that the link points to the get '/sessions/login' route.

Let's move on to step 2, the building of our user sign-up flow.

Step 2: User Sign-up

  • In your controller you should see two routes dedicated to sign-up. Let's take a look at the first route, get '/registrations/signup', which is responsible for rendering the sign-up template.

get '/registrations/signup' do
    erb :'/registrations/signup'
end
  • Open up app/views/registrations/signup.erb. Our signup form needs fields for name, email, and password. It needs to POST data to the '/registrations' path, so your form action should be '/registrations' and your form method should be POST.

  • Once you've written your form, go ahead and add the line puts params inside the post '/registrations' route in the controller. Then, fill out the form in your browser and hit the "Sign Up" button.

  • Hop on over to your terminal and you should see the params outputted there. It should look something like this (but with whatever info you entered into the form):

{"name"=>"Beini Huang", "email"=>"beini@bee.com", "password"=>"password"}
  • Okay, so we're inside our post '/registrations' route, and we have our params hash that contains the user's name, email, and password. Inside the post '/registrations' route, place the following code:

@user = User.new(name: params["name"], email: params["email"], password: params["password"])
@user.save
  • We did it! We registered a new user! Now we just need to sign them in. On the following line, set the session[:user_id] equal to our new user's ID:

session[:user_id] = @user.id
  • Take a look at the last line of the method:

Now that we've signed up and logged in our user, we want to take them to their homepage.

Go ahead and run the test suite again and you should see that almost all of the user sign-up tests are passing.

Step 3: Fetching the Current User

Open up the view file: app/views/users/home.erb and look at the following line of code:

"Welcome, <%=@user.name%>!"

Looks like this view is trying to operate on a @user variable. We know that the only variables that a view can access are instance variables set in the controller route that renders that particular view page. Let's take a look at the route in our controller that corresponds to the /users/home view.

Remember, after a user signs up and is signed in via the code we wrote in the previous step, we redirect to the '/users/home' path. Let's check out that route right now.

  • Again, take a look at the controller. You should see the get '/users/home' route. First, this route finds the current user based on the ID value stored in the session hash. Then, it sets an instance variable, @user, equal to that found user, allowing us to access the current user in the corresponding view page. Let's set it up:

get '/users/home' do
  @user = User.find(session[:user_id])
  erb :'/users/home'
end
  • Run the tests again and we should be passing all of our user sign up tests.

Step 4: Logging In

  • Go back to your homepage and look at the second of the two links:

<a href="/sessions/login">Log In</a>
  • This is a link to the get '/sessions/login' route. Checkout the two routes defined in the controller for logging in and out. We have a get '/sessions/login' route and a post '/sessions' route.

  • Open up app/views/sessions/login.erb. We need a form that sends a POST request to /sessions and has input fields for email and password. Don't forget to add a submit button that says 'Log In'. Then, to test that everything is working as expected, place the line puts params in the post '/sessions' route. In your browser, fill out the form and hit 'Log In'.

  • In your terminal, you should see the outputted params hash looking something like this (but with whatever information you entered into the login form):

{"email"=>"beini@bee.com", "password"=>"password"}
  • Inside the post '/sessions' route, let's write the lines of code that will find the correct user from the database and log them in by setting the session[:user_id] equal to their user ID.

@user = User.find_by(email: params["email"], password: params["password"])
session[:user_id] = @user.id
  • Notice that the last line of the route redirects the user to their homepage. We already coded the '/users/home' route in the controller to retrieve the current user based on the ID stored in session[:user_id].

  • Run the test suite again and you should be passing the user login tests.

Step 5: Logging Out

  • Open up app/views/users/home.erb and check out the following link:

<a href="/sessions/logout">Log Out</a>
  • We have a link that takes us to the get '/sessions/logout' route, which is responsible for logging us out by clearing the session hash.

  • In the get '/sessions/logout' route in the controller, put:

  • Run the test suite again, and you should be passing everything.

Conclusion

Phew! This was a big code-along, and we were introduced to some new concepts. Before moving on, play around with your app a bit. Practice signing up, logging out, and logging in, and get used to the general flow.

There's a lot to think about here, but here are a few takeaways:

  • Separate out your views into sub-folders according to their different concerns / controller routes.

  • Signing up for an app is nothing more than submitting a form, grabbing data from the params hash, and using it to create a new user.

  • Logging in is nothing more than locating the correct user and setting the :id key in the session hash equal to their user ID.

  • Logging out is accomplished by clearing all of the data from the session hash.

Another important takeaway from this lab is a general understanding of the flow of information between the different routes and views of an application. If you're still confused by the flow of signing up and logging in/out, try drawing it out. Can you map out where your web requests go from the point at which you click the "Sign Up" link all the way through until you log out and then attempt to log back in? Give it a shot.

PreviousSinatra ActiveRecord CRUDNextSinatra Sessions Lab - User Logins

Last updated 5 years ago

Start up your app by running shotgun in the terminal. Visit the homepage at . You should see a message that welcomes you to Hogwarts and shows you a link to sign up and a link to log in.

Navigate to . You should see a page that says 'Sign Up Below:'. Let's make a sign-up form!

The get /sessions/login' route renders the login view page. Restart your app by executing Ctrl + C and then typing shotgun in your terminal. Navigate back to the root page, , and click on the 'Log In' link. It should take you to a page that says 'Log In Below:'. Let's create our login form!

Clone this lab here:

localhost:9393
localhost:9393/registrations/signup
localhost:9393
https://github.com/learn-co-curriculum/sinatra-user-auth