Authentification par Token en mode API et Basic en mode navigateur

This commit is contained in:
Jérémy Lecour 2022-01-25 23:31:08 +01:00 committed by Jérémy Lecour
parent 41d1d6d8fe
commit e13fb4828a
13 changed files with 179 additions and 203 deletions

View file

@ -1,30 +0,0 @@
class Api::V1::ApiKeysController < Api::V1::BaseController
# include ApiKeyAuthenticable
# # Require API key authentication
# prepend_before_action :authenticate_with_api_key!, only: %i[index destroy]
def index
render json: current_bearer.api_keys
end
def create
authenticate_with_http_basic do |email, password|
user = User.find_by email: email
if user&.authenticate(password)
api_key = user.api_keys.create! token: SecureRandom.hex
render json: api_key, status: :created and return
end
end
render status: :unauthorized
end
def destroy
api_key = current_bearer.api_keys.find(params[:id])
api_key.destroy
end
end

View file

@ -1,4 +1,9 @@
class Api::V1::BaseController < ApplicationController
include ApiKeyAuthentication
# Require API key authentication
prepend_before_action :authenticate_with_api_key!
# before_action :authenticate
protect_from_forgery with: :null_session

View file

@ -12,6 +12,7 @@ class Api::V1::ChecksController < Api::V1::BaseController
end
private
# Use callbacks to share common setup or constraints between actions.
def set_check
@check = Check.find(params[:id])

View file

@ -1,5 +1,5 @@
class ApplicationController < ActionController::Base
include Authentication
include BasicAuthentication
include Pundit
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

View file

@ -0,0 +1,3 @@
class AuthenticatedController < ApplicationController
before_action :authenticate_user!
end

View file

@ -1,4 +1,4 @@
class ChecksController < ApplicationController
class ChecksController < AuthenticatedController
before_action :set_check, only: %i[ show edit update destroy ]
# GET /checks or /checks.json

View file

@ -1,31 +0,0 @@
module ApiKeyAuthenticatable
include ActionController::HttpAuthentication::Basic::ControllerMethods
include ActionController::HttpAuthentication::Token::ControllerMethods
extend ActiveSupport::Concern
attr_reader :current_api_key
attr_reader :current_bearer
# Use this to raise an error and automatically respond with a 401 HTTP status
# code when API key authentication fails
def authenticate_with_api_key!
@current_bearer = authenticate_or_request_with_http_token &method(:authenticator)
end
# Use this for optional API key authentication
def authenticate_with_api_key
@current_bearer = authenticate_with_http_token &method(:authenticator)
end
private
attr_writer :current_api_key
attr_writer :current_bearer
def authenticator(token, options)
@current_api_key = ApiKey.authenticate_by_token token
current_api_key&.bearer
end
end

View file

@ -0,0 +1,31 @@
module ApiKeyAuthentication
include ActionController::HttpAuthentication::Basic::ControllerMethods
include ActionController::HttpAuthentication::Token::ControllerMethods
extend ActiveSupport::Concern
attr_reader :current_api_key
attr_reader :current_bearer
# Use this to raise an error and automatically respond with a 401 HTTP status
# code when API key authentication fails
def authenticate_with_api_key!
@current_bearer = authenticate_or_request_with_http_token &method(:authenticator)
end
# Use this for optional API key authentication
def authenticate_with_api_key
@current_bearer = authenticate_with_http_token &method(:authenticator)
end
private
attr_writer :current_api_key
attr_writer :current_bearer
def authenticator(token, options)
@current_api_key = ApiKey.authenticate_by_token token
current_api_key&.bearer
end
end

View file

@ -1,58 +0,0 @@
module Authentication
extend ActiveSupport::Concern
included do
before_action :current_user
helper_method :current_user
helper_method :user_signed_in?
end
def authenticate_user!
store_location
redirect_to login_path, alert: "You need to login to access that page." unless user_signed_in?
end
def login(user)
reset_session
user.regenerate_session_token
session[:current_user_session_token] = user.reload.session_token
end
def forget(user)
cookies.delete :remember_token
user.regenerate_remember_token
end
def logout
user = current_user
reset_session
user.regenerate_session_token
end
def redirect_if_authenticated
redirect_to root_path, alert: "You are already logged in." if user_signed_in?
end
def remember(user)
user.regenerate_remember_token
cookies.permanent.encrypted[:remember_token] = user.remember_token
end
def store_location
session[:user_return_to] = request.original_url if request.get? && request.local?
end
private
def current_user
Current.user ||= if session[:current_user_session_token].present?
User.find_by(session_token: session[:current_user_session_token])
elsif cookies.permanent.encrypted[:remember_token].present?
User.find_by(remember_token: cookies.permanent.encrypted[:remember_token])
end
end
def user_signed_in?
Current.user.present?
end
end

View file

@ -0,0 +1,58 @@
module BasicAuthentication
extend ActiveSupport::Concern
included do
before_action :current_user
helper_method :current_user
helper_method :user_signed_in?
end
def authenticate_user!
store_location
redirect_to login_path, alert: "You need to login to access that page." unless user_signed_in?
end
def login(user)
reset_session
user.regenerate_session_token
session[:current_user_session_token] = user.reload.session_token
end
def forget(user)
cookies.delete :remember_token
user.regenerate_remember_token
end
def logout
user = current_user
reset_session
user.regenerate_session_token
end
def redirect_if_authenticated
redirect_to root_path, alert: "You are already logged in." if user_signed_in?
end
def remember(user)
user.regenerate_remember_token
cookies.permanent.encrypted[:remember_token] = user.remember_token
end
def store_location
session[:user_return_to] = request.original_url if request.get? && request.local?
end
private
def current_user
Current.user ||= if session[:current_user_session_token].present?
User.find_by(session_token: session[:current_user_session_token])
elsif cookies.permanent.encrypted[:remember_token].present?
User.find_by(remember_token: cookies.permanent.encrypted[:remember_token])
end
end
def user_signed_in?
Current.user.present?
end
end

View file

@ -50,4 +50,3 @@ class PasswordsController < ApplicationController
params.require(:user).permit(:password, :password_confirmation)
end
end

View file

@ -28,4 +28,3 @@ class SessionsController < ApplicationController
def new
end
end

View file

@ -4,7 +4,6 @@ Rails.application.routes.draw do
namespace :v1 do
defaults format: :json do
get '/ping', to: 'base#ping'
resources :api_keys, path: 'api-keys', only: %i[index create destroy]
resources :checks, only: [:create]
end
end