Skip to content

Commit cf0d606

Browse files
committed
Ensure CSRF protection runs before all other filters
Rails 5.2 does not prepend forgery protection before all other controller filters anymore. If you access the `current_user` method in an before filter (for instance because you want to store its id in an error tracking service context) you will see a "Can't verify CSRF token authenticity" error in your logs and the login fails. Fixed by prepending the CSRF forgery protection in our sessions controller. Closes #80
1 parent dcfa632 commit cf0d606

4 files changed

Lines changed: 32 additions & 8 deletions

File tree

app/controllers/alchemy/user_sessions_controller.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ module Alchemy
22
class UserSessionsController < ::Devise::SessionsController
33
include Alchemy::Admin::Locale
44

5+
protect_from_forgery prepend: true
6+
57
before_action except: 'destroy' do
68
enforce_ssl if ssl_required? && !request.ssl?
79
end
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
class ApplicationController < ActionController::Base
2-
# Prevent CSRF attacks by raising an exception.
3-
# For APIs, you may want to use :null_session instead.
4-
protect_from_forgery with: :exception
2+
# @See https://github.com/AlchemyCMS/alchemy-devise/issues/80
3+
before_action { current_user }
54
end

spec/dummy/config/environments/test.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@
2626
config.action_dispatch.show_exceptions = false
2727

2828
# Disable request forgery protection in test environment.
29-
config.action_controller.allow_forgery_protection = false
30-
31-
# Store uploaded files on the local file system in a temporary directory
32-
# config.active_storage.service = :test
29+
config.action_controller.allow_forgery_protection = true
3330

3431
config.action_mailer.perform_caching = false
3532

spec/features/login_feature_spec.rb

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
require 'spec_helper'
22

33
describe "Login: " do
4-
context "If users present" do
4+
context "If user is present" do
5+
let!(:user) do
6+
Alchemy::User.create!(
7+
login: 'admin',
8+
email: 'admin@example.com',
9+
password: 's3cr3t',
10+
password_confirmation: 's3cr3t',
11+
alchemy_roles: %w[admin]
12+
)
13+
end
14+
515
let!(:default_key) { Devise.authentication_keys }
616

717
before do
@@ -13,6 +23,14 @@
1323
visit '/admin/login'
1424
expect(page).to have_field('user_login')
1525
end
26+
27+
it "works" do
28+
visit '/admin/login'
29+
fill_in 'user_login', with: user.login
30+
fill_in 'user_password', with: user.password
31+
click_button 'Login'
32+
expect(page).to have_content('Welcome back admin')
33+
end
1634
end
1735

1836
context "with default Devise configuration" do
@@ -25,6 +43,14 @@
2543
expect(page).to have_field('user_email')
2644
end
2745

46+
it "works" do
47+
visit '/admin/login'
48+
fill_in 'user_email', with: user.email
49+
fill_in 'user_password', with: user.password
50+
click_button 'Login'
51+
expect(page).to have_content('Welcome back admin')
52+
end
53+
2854
after do
2955
Devise.authentication_keys = default_key
3056
end

0 commit comments

Comments
 (0)