User authentication

One important aspect of application development that often gets overlooked is user authentication. Of the several ways to implement it, the question of password encryption comes into play. Bcrypt is a cryptographic standard for password encryption, and is the most recommended. Luckily, you don’t have to implement Bcrypt yourself, there’s a gem for it. Add gem 'bcrypt-ruby' anywhere in your Gemfile to get started.

After bundle installing, create a User. In order to take advantage of the Bcrypt gem, your user model must have a column called password_digest. This will hold the encrypted version of the password that your user sets when signing up.

Next, in your models/User.rb file, add the has_secure_password method. The file should look like this:

```ruby /models/User.rb

class User < ActiveRecord::Base

has_secure_password

end


This method is provided by the Bcrypt gem, validating for the presence of <code>password</code> and <code>password_confirmation</code> attributes when a user is created. If both attributes are present and match each other, Bcrypt combines the two attributes and encrypts the password. Here's an example of what it should look like in the Rails console:

```plain Rails console

2.0.0-p195 :001 > User.last
  User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
  => #<User id: 3, name: "addie", email: "addie@example.com", password_digest: "$2a$10$F.MLoSYigR6TZDXhN3FE4.DpSvcf1PFFQXEU/vq8oIEO..."

One really important thing to remember is that you never directly interact with the password_digest attribute. It’s automatically generated from the password and password_confirmation attributes that you collect from the params. So, when asking for a user to enter a password on a sign up form, don’t have the form submit a parameter called password_digest, the transaction will be rolled back and the user won’t be created. Remember that you only need both attributes when first creating a user. Once a user is in the database, you only need to check against the password_digest.

Now that a user can be created, they probably want to sign in. Since we already know that for a user to be recognized as being signed in, you need to set a session cookie. Even though you’re not actually creating a database model to represent a session, you still need a controller to be able to serve up a page for signing in and the ability to set session cookies.

```ruby sessions_controller.rb

class SessionsController < ApplicationController def new # In your routes, this action should render a sign in page. end

def create @user = User.find_by_email(params[:email]) # If a user in the database is found with the email that the user entered. if @user # The #authenticate method checks the entered password against the password digest in the database. if @user.authenticate(params[:password]) # If the passwords match, the session cookie is set to the user’s id, allowing you to tailor content specific to that user. session[:user_id] = @user.id redirect_to wherever_path else render ‘new’ end else render ‘new’ end end

# This is used to log out. def destroy reset_session redirect_to login_path end end

That's pretty much it for rolling your own user authentication. 

### Your app as an API ###
When developing apps, taking advantages of third-party APIs can be really helpful. You can pull in data via easy to use JSON and manipulate it within the context of your app to do some really interesting things. For instance, pulling latitude and longitude data from Chicago's crime API and plotting it on a Google map. APIs are essentially the channels through which apps can talk to each other. Before last week, I had wondered how developers actually expose their app's data as an API. The trick to doing this, Jeff taught us, is to change the format of the HTTP request being made. 

Up to this point we have viewed HTTP requests as having only two parts: The type of request(e.g., GET) and the URL. In order to expose your app's data as an API, JSON in particular, you have to manipulate a third header of an HTTP request: the format or MIME type. The format determines how data from the application is sent back to the client. You can change the format type of requests in your controller. To do this, we use the <code>respond_to</code> method. This tells Rails to be prepared to send back our data in different formats that we specify if the client requests that format. Here's an example:

```ruby users_controller.rb
class UsersController < ActionController
  def show
    @user = User.find_by_id(params[:id])
	
	  respond_to do |format|
	    format.html
	    format.json
	  end
  end
end

This allows for the client to either go to the HTML page for this action, or request to same data in the JSON format. Your app now has a JSON API, being able to be consumed by other apps that want to manipulate your data.

Model Scoping

When refactoring your app, taking database logic out of your controller and putting it in your model is usually a good idea. This abstraction helps your controller logic communicate more clearly what data it’s serving up to the views. The way to usually do this is define a method in your model to make that query. For example, if you wanted to find all users that were born in the 90’s, instead of creating another instance variable in your index action like this:

```ruby users_controller.rb class UsersController < ApplicationController def index @users = Users.all @nineties = @users.where(year_of_birth: 1990..1999) end end

You would define this method is your <code>User</code> model:

```ruby user.rb
class User < ActiveRecord::Base
  def nineties
    User.where(year_of_birth: 1990..1999)
  end
end

Now you can call this method in the view and the intention of the code is very clear on what you are trying to display:

```erb index.html.erb

Users

<% @users.nineties.each do |user| %> #display the users <% end %>

This is great, but it turns out that there's a shorter way to do this called model scoping. Scoping allows you to specify commonly used queries which can be referenced as method calls on the models. Scope methods will return an <code>ActiveRecord::Relation</code> object which will allow for more methods or scopes to be called on it.

```ruby user.rb
class User < ActiveRecord::Base
  scope :nineties, -> { where(year_of_birth: 1990..1999) }
end

The arrow pointing to the block represents a call to a lambda, which, if I can fully wrap my head around it, I will write about in my next post.