Skip to content

Commit

Permalink
JWT authentication from scratch
Browse files Browse the repository at this point in the history
  • Loading branch information
excid3 committed Jan 6, 2017
1 parent 645408a commit dc74a64
Show file tree
Hide file tree
Showing 13 changed files with 478 additions and 1 deletion.
3 changes: 3 additions & 0 deletions Gemfile
Expand Up @@ -46,3 +46,6 @@ end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

gem 'devise'
gem 'jwt'
15 changes: 15 additions & 0 deletions Gemfile.lock
Expand Up @@ -39,6 +39,7 @@ GEM
minitest (~> 5.1)
tzinfo (~> 1.1)
arel (7.1.4)
bcrypt (3.1.11)
builder (3.2.2)
byebug (9.0.6)
coffee-rails (4.2.1)
Expand All @@ -50,6 +51,12 @@ GEM
coffee-script-source (1.12.1)
concurrent-ruby (1.0.2)
debug_inspector (0.0.2)
devise (4.2.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.1)
responders
warden (~> 1.2.3)
erubis (2.7.0)
execjs (2.7.0)
ffi (1.9.14)
Expand All @@ -63,6 +70,7 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jwt (1.5.6)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
Expand All @@ -80,6 +88,7 @@ GEM
nio4r (1.2.1)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
orm_adapter (0.5.0)
puma (3.6.2)
rack (2.0.1)
rack-test (0.6.3)
Expand Down Expand Up @@ -111,6 +120,8 @@ GEM
rb-fsevent (0.9.8)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
responders (2.3.0)
railties (>= 4.2.0, < 5.1)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
Expand Down Expand Up @@ -141,6 +152,8 @@ GEM
thread_safe (~> 0.1)
uglifier (3.0.4)
execjs (>= 0.3.0, < 3)
warden (1.2.6)
rack (>= 1.0)
web-console (3.4.0)
actionview (>= 5.0)
activemodel (>= 5.0)
Expand All @@ -156,8 +169,10 @@ PLATFORMS
DEPENDENCIES
byebug
coffee-rails (~> 4.2)
devise
jbuilder (~> 2.5)
jquery-rails
jwt
listen (~> 3.0.5)
puma (~> 3.0)
rails (~> 5.0.0, >= 5.0.0.1)
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/api/v1/authentication_controller.rb
@@ -0,0 +1,12 @@
class Api::V1::AuthenticationController < ApiController
skip_before_action :authenticate_token!

def create
user = User.find_by(email: params[:user][:email])
if user.valid_password? params[:user][:password]
render json: { token: JsonWebToken.encode(sub: user.id) }
else
render json: { errors: ["Invalid email or password"] }
end
end
end
16 changes: 16 additions & 0 deletions app/controllers/api_controller.rb
@@ -1,9 +1,25 @@
class ApiController < ApplicationController
skip_before_action :verify_authenticity_token

before_action :set_default_format
before_action :authenticate_token!

private

def set_default_format
request.format = :json
end

def authenticate_token!
payload = JsonWebToken.decode(auth_token)
@current_user = User.find(payload["sub"])
rescue JWT::ExpiredSignature
render json: {errors: ["Auth token has expired"]}, status: :unauthorized
rescue JWT::DecodeError
render json: {errors: ["Invalid auth token"]}, status: :unauthorized
end

def auth_token
@auth_token ||= request.headers.fetch("Authorization", "").split(" ").last
end
end
10 changes: 10 additions & 0 deletions app/models/json_web_token.rb
@@ -0,0 +1,10 @@
class JsonWebToken
def self.encode(payload)
expiration = 30.minutes.from_now.to_i
JWT.encode payload.merge(exp: expiration), Rails.application.secrets.secret_key_base
end

def self.decode(token)
JWT.decode(token, Rails.application.secrets.secret_key_base).first
end
end
6 changes: 6 additions & 0 deletions app/models/user.rb
@@ -0,0 +1,6 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end

0 comments on commit dc74a64

Please sign in to comment.