Monthly Archives: March 2015

Why you don’t need Devise. Get a better understanding of authentication!

Devise gem comes with a lot of extra features you don’t need.  What happens is you end up learning everything about using a specific gem and neglect to understand how to learn how to create an app with rails.  First a few things on authentication.  Your app should never know your password, it shouldn’t be able to find it or even decrypt it.

You should save your password as a One-way hash.  So we don’t decrypt it, but instead turn it into a string, stored as a hash, and match those hashes.  That is how password authentication works, a one way authentication.  Other methods are more prone to attack.

Say we already have a basic user class with some basic attributes.

1- We need to add a column to store and keep the long token, we must call it password_digest since we are using ruby has_secure_password. (shown later)

rails g migration add_password_digest_to_users

in the migration file

def change

add_column :users, :password_digest, :string

end

2- Go to your User model and add this line, has_secure_password

3- Add gem ‘bcrypt’, version 3.0.1.  This gem has the library that does the actual hashing.  errors might arise make sure to use the right version.  There is a lot of math involved in hashing algorithms, bcrypt comes equipped.  Remember to bundle install.

Now we can test it out on rails console.

>> u = User.new

>> u.username = ‘bob’

>> u.save => gives you false, why?

>> u.errors => password cant be blank

This occurs because has_secure_password has some rails built in validations.  Once again rails is doing more than we want.  To bypass this is just add ‘validations: false’ to the User class

has_secure_password validations: false

>> u.save => true

The has_secure_password gives us the password setter method

>> u.password = ‘password’

>> u.save

– If you look at the SQL statements created by the above.  You see it didn’t save password but the password_digest.  Password is a virtual attribute, it’s a setter, and it allows us to set values into the password digest.  Where it automatically hashes it for us using bcrypt.

So in the database you will see some long crazy string.  This is the result of our one way hash. So we have a setter method, but do we have a getter method?  The answer is no.

Log out of the rails console and relog back in.

>> u= User.find_by username: ‘bob’

>> u.password => nil

You might have seen a value for u.password before you logged out of rails console before but that is because it was ‘in memory’.

So now knowing this, how do we authenticate our application?

We just performed a one way hash on a string.  Which produces our really long token, and if those tokens match then it means those strings are correct.

– has_secure_password also gives us

>> u.authenticate(‘teststring’) method, which just gives us true or false.  If the hash tokens don’t match they return false.  If they match they return the user object, which evaluates to true.

>> u.authenticate(‘password’)

=> user object…

That’s the way we can use has_secure_password to introduce authentication to our rails app.

Advertisements
Tagged , , ,

Don’t delete your migrations!

Rails migration pushing issues

Say you deleted a migration so when you push all your migration histories to heroku

it gives you migration errors.

You can type

rake db:migrate:status

This will give you history of migrations and whats missing,

 Status   Migration ID    Migration Name

————————————————–

   up     20150207013411  ********** NO FILE **********

   up     20150207020939  Create users

   up     20150207021329  Add user id to posts

   up     20150207022740  Create comments

   up     20150207023755  Create categories

   up     20150207063021  Add columns to users

   up     20150207075531  Create post categories

   up     20150208061306  Add column to posts

   up     20150217172541  Add pass word digest to users

   up     20150305203015  Create votes

   up     20150309223946  Add column to comments

  down    20150313162219  Create posts

you can then copy that migration ID and create a new file in your migrations with that migration ID number, and code inside the file.

This will put that code in the proper place so you can run migrations smoothly on heroku or locally.

mysql database creation questions!

This post is going to be broad and fragmented, so forgive me.  I have been using rails to create databases with active record for my projects which is basically a builtin feature in Rails that helps with your database table creation.  It allows you to use ruby for your database and rails conventions takes care of the rest.  But there are still many times you will need to know SQL in more specific senarios such as redoing old sites into rails and perhaps to maximize performance N+1 query problems.

When building a SQL database you it helps to obviously use a diagram whether by hand or with some program like mysql workbench.  This helps you set the tables visually, make the associations between tables, and get a broad look at what you are creating.  If you follow the programs conventions it will even write the SQL statements for you.

I know there are many books out there but I when ask more experienced developers what I should read to better my understanding of actually creating a working database for some project I get blank stares.  It looks like the process isn’t well documented it is just something you have to learn by experience.  The fundamentals and syntax to guide you, the rest are a few tips here and there, but mostly experience.  Which frustrates the heck out of me, because that takes time!  Anyway here are a few tips from blogs I’ve read, maybe it will help you guys!

– what is the nature of your application, Transactional or Analytical?

Transactional meaning more of a CRUD app, such as a blog, or store application with buying and selling.  Where the end user will be creating, updating, deleting records.  Analytical applications are more for reporting, analyzing.  They typically have less inserts, and updates.  For this database you want to get and analyze data with priority being speed for those actions.  This will affect your decision to go for a more normalized table structure or not.  Analytical databases can benefit form having more de-normalized structure.  Of course situation dictates.

I’ll put up more tips on future posts.

Keep moving

– won