DEV Community

Victor Magarlamov
Victor Magarlamov

Posted on

HTTP [Basic and Token] authentication

In this post I show you how to implement HTTP-authentication between the client (JavaScript) and the server (RubyOnRails).

Bit of theory

  1. When an unauthenticated client sends request to the protected resource, the server responses with an 401 Unauthorized HTTP status and adds a WWW-Authenticate header, which contains the authentication scheme and parameters.
  2. When a client sends a request with an Authorization header, the server checks the credentials in this header and response with an 200 OK or with an 403 Forbidden HTTP status.

Bit of practice

First, we need two models: User и AuthToken.

class User < ApplicationRecord
  has_many :auth_tokens

class AuthToken < ApplicationRecord
  belongs_to :user

  before_create :set_value

  def set_value
    self.value = SecureRandom.hex(32)

Authenticate with HTTP Basic

There are some useful modules for HTTP Authentication in RubyOnRails. Lets add one of them to our controller.

class ApplicationController < ActionController::API
  include ActionController::HttpAuthentication::Basic::ControllerMethods

Then we create a controller for user authentication. After receiving the POST-request, it checks user credentials. If successful, it sends the token to the user. A little later we do the Token authentication using the one.

class AuthenticationsController < AplicationController
  def create
    authenticate_with_http_basic do |login, password|
      user = User.find_by_login(login)

      if user&.authenticate(password)
        token = user.auth_tokens.create!
        render json: { token: token.value } and return

    render status: :unauthorized

Lets create a JavaScript method which helps us get this token.

function authenticate(login, password) {
  const credentials = window.btoa(`${login}:${password}`);
  const headers = {};

  headers[‘Authorization’] = `Basic ${credentials}`;

  return fetch(‘/authentications’,  {method: ‘post’, headers} ).then(...)

Please note how we send the credentials. There is a rule for string formatting:

scheme + space + login + ‘:’ + password

And all is encoded by base64, except the name of the scheme.

Authenticate with HTTP Token

Well we successfully passed Basic authentication and got the token. Lets add Token authentication.

class ApplicationController < ActionController::API
  include ActionController::HttpAuthentication::Basic::ControllerMethods
  include ActionController::HttpAuthentication::Token::ControllerMethods

  attr_reader :current_user


  def authenticate_by_token
    authenticate_or_request_with_http_token do |http_token|
      token = AuthToken.find_by_value(http_token)
      @current_user = token.user if token

And apply it to a controller.

class UsersController < AplicationController
   before_action :authenticate_by_token

  def create

Now to get access to the protected resource, just add the Authorization header.

headers[‘Authorization’] = `Token ${token}`;


Top comments (0)