Skip to content

Commit

Permalink
Use button_to to generate a POST form, disable turbo with OmniAuth
Browse files Browse the repository at this point in the history
This changes the OmniAuth "sign in" links to use buttons, which can be
wrapped in an actual HTML form with a method POST, making them work
better with and without Turbo in the app. It doesn't require rails/ujs
anymore in case of a non-Turbo app, as it previously did with links +
method=POST.

Turbo is disabled for those OmniAuth buttons, as they simply don't work
trying to follow the redirect to the OmniAuth provider via fetch,
causing CORS issues/errors.
  • Loading branch information
carlosantoniodasilva committed Feb 1, 2023
1 parent f08e0ad commit 88625d4
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 15 deletions.
23 changes: 12 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
* `:turbo_stream` is now treated as a navigational format, so it works like HTML navigation when using Turbo. Note: if you relied on `:turbo_stream` to be treated as a non-navigational format before, you can reconfigure your `navigational_formats` in the Devise initializer file to exclude it.
* Devise requires the latest `responders` version, which allows configuring the status used for validation error responses (`error_status`) and for redirects after POST/PUT/PATCH/DELETE requests (`redirect_status`). For backwards compatibility, Devise keeps `error_status` as `:ok` which returns a `200 OK` response, and `redirect_status` to `:found` which returns a `302 Found` response, but you can configure it to return `422 Unprocessable Entity` and `303 See Other` to match the behavior expected by Hotwire/Turbo:

```ruby
# config/initializers/devise.rb
Devise.setup do |config|
# ...
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
# ...
end
```

These configs are already generated by default with new apps, and existing apps may opt-in as described above. Note that these defaults may change in future versions of Devise, to better match the Rails + Hotwire/Turbo defaults across the board.
```ruby
# config/initializers/devise.rb
Devise.setup do |config|
# ...
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
# ...
end
```

These configs are already generated by default with new apps, and existing apps may opt-in as described above. Note that these defaults may change in future versions of Devise, to better match the Rails + Hotwire/Turbo defaults across the board.
* OmniAuth "Sign in with" links were changed to buttons that generate HTML forms with method=POST, instead of using link + method=POST that required rails/ujs to work. Since rails/ujs is no longer the default for new Rails apps, this allows the OmniAuth buttons to work in any scenario, with or without rails/ujs and/or Turbo. This only affects apps that are using the default `devise/shared/_links.html.erb` partial from Devise with OmniAuth enabled.

### 4.8.1 - 2021-12-16

Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/shared/_links.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
<% end %>
<% end %>
8 changes: 6 additions & 2 deletions test/integration/omniauthable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,17 @@ def stub_action!(name)

test "generates a link to authenticate with provider" do
visit "/users/sign_in"
assert_select "a[href=?][data-method='post']", "/users/auth/facebook", text: "Sign in with FaceBook"
assert_select "form[action=?][method=post]", "/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end

test "generates a proper link when SCRIPT_NAME is set" do
header 'SCRIPT_NAME', '/q'
visit "/users/sign_in"
assert_select "a[href=?][data-method='post']", "/q/users/auth/facebook", text: "Sign in with FaceBook"
assert_select "form[action=?][method=post]", "/q/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end

test "handles callback error parameter according to the specification" do
Expand Down
2 changes: 1 addition & 1 deletion test/integration/timeoutable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def last_request_at
follow_redirect!

assert_response :success
assert_contain 'Sign in'
assert_contain 'Log in'
refute warden.authenticated?(:user)
end

Expand Down

0 comments on commit 88625d4

Please sign in to comment.