# API Authentication in Elixir Phoenix - Part 1

Authentication is a very important aspect of any application. It restricts the unknown user to access anyone's data. We will be going to implement token-based authentication. This blog will be a continuation of our blog "JSON-API with Elixir-phoenix". We developed a "post" resource with an `index` action. Right now that resource is public and anyone can access those blog lists. Imagine, if you want that endpoint to be accessed only by the registered user. How this can be achieved? The answer is authentication. There are many strategies to authenticate a user. We are going to implement token-based authentication in Elixir-Phoenix.

This blog is 2 part series. 
- Part 1: It will be about securing user password as hash using Bcrypt strategy (This is Part 1)
- Part 2: We will be adding a secured password hash in API flow.

We are going to split this blog into 3 parts:
- Hashing Password
- Storing Password as a hash
- Testing the password hash

### Password Hashing:
We don't store user passwords directly in the database, instead, we save `password_hash`. We will be
using the Bcrypt algorithm for hashing our passwords. There is no way to backtrack or get a password from password_hash.
It is one of the very secure encryption algorithms for hashing passwords. There is a library called 
`comeonein` in a hex that will help manage password salting and hashing using bcrypt so that we can
avoid low-level details.

We are going to install `comeonein` and `bcrypt_elixir` for hashing strategy.

We are going to create a migration schema for our user's table.
`mix phx.gen.context Blog User users email:string username:string password_hash:string`

This will create migration files, now we will run this migration by running `mix ecto.migrate`.

Now you open the `User` module, where you have the `schema` and `changeset` function you defined while creating
migration. We have to do some extra work before storing `password_hash`. For that we are going to add
two extra fields `password` and `password_confirmation` in the User schema, which are going to be `virtual` since we are not going to store that.

We are going to replace `password_hash` field with `password` and `password_confirmation` in `cast` and `validate_required`function.
We are also going to add validation for the uniqueness of our `email`. We are going to add `unsafe_validate_required` 
in function pipeline after `validate_required`. Also, for password confirmation, we are going to add
the `validate_confirmation` function from ecto changeset. 

So below are the changes till now in the `changeset` function.
```
  def changeset(%User{} = user, attrs) do
    user
    |> cast(attrs, [:email, :username, :password, :password_confirmation])
    |> validate_required([:email, :username, :password, :password_confirmation])
    |> unsafe_validate_unique([:email], BlogApi.Repo)
    |> validate_confirmation(:password)
  end
```

### Storing Password as a hash:
Till now we have focussed only on adding the `password` and `confirmation` fields in the changeset pipeline.
Now we will be working on hashing of the password. We are going to add one more function in the changeset pipeline
which is going to convert user-entered passwords into hash. So, we create a function called `hash_password` which will take `changeset` as a parameter. We will hash the password using `Bcrypt.hashpwsalt`function.

```
def hash_password(changeset) do
  hash = Bcrypt.hashpwsalt(get_field(changeset, :password))
  put_change(changeset, :password_hash, hash)
end
```

This is going to hash the password and set it on the `password` field in the schema and return the updated changeset.


### Testing the password hash: 
Now, we are going to test the password hash in the iex shell. Turn over to your terminal and run `iex -S mix`
and alias `User` and `Repo` module. Create a variable `hash=%{email: "abc@gmail.com", password: "password", password_confirmation: "password"}``

Now, will create the changeset, `user = User.changeset(%User{}, hash)`
This is going to changeset struct as given below:

```
  #Ecto.Changeset<
    action: nil,
    changes: %{
      email: "abc@gmail.com",
      password: "password",
      password_confirmation: "password",
      password_hash: "$2b$12$iMn.3MoDR12Ryw/1M8enPeYqiqlHS.P5PGNWYKKDjjA8dWU0OyzGG"
    },
    errors: [],
    data: #BlogApi.Blog.User<>,
    valid?: true
  >
```

As you can see it has generated the struct with some random hash in the `password_hash`field and there is no error in the `errors` field. Now, we will commit this changeset to the Repo by running `Repo.insert(user)`.

This will push changes to the database. We can confirm this by running the following command
`Repo.get!(User, 1)`. 

This is the end of part 1, where we have encrypted the password. In the second part, we will add this password encryption in the API Authentication flow.

