rodauth-omniauth 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -32
- data/lib/rodauth/features/omniauth.rb +10 -7
- data/rodauth-omniauth.gemspec +2 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c91c4429c36390bbede1d97214cdb6a40c5a6f5d9255c379f3b17d026cee88c9
|
4
|
+
data.tar.gz: 8e09d6d3c5d4d9eb0022dd5696e1370fc82c22bd068ec5b883212f2117ae3c47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03e77668f1f2c2076f003ac455c1f57dcfd5b60f7096cc77e5fe0918bf6484814ab02304eb9286e5323c42c2115102b262edb55dc41174dc0574c9ae0e6c84cc
|
7
|
+
data.tar.gz: f90369c94f3d9baf82dda2490ff716e543cd6cd09a6c8b856b2ba41c0594bcce69a489755520e2aea898eaf6907611d31d53c7cbf2a5f3f0fff51a457511012d
|
data/README.md
CHANGED
@@ -10,6 +10,10 @@ Add the gem to your project:
|
|
10
10
|
$ bundle add rodauth-omniauth
|
11
11
|
```
|
12
12
|
|
13
|
+
> [!NOTE]
|
14
|
+
> Rodauth's CSRF protection will be used for the request validation phase, so there is no need for gems like `omniauth-rails_csrf_protection`.
|
15
|
+
|
16
|
+
|
13
17
|
## Usage
|
14
18
|
|
15
19
|
You'll first need to create the table for storing external identities:
|
@@ -46,17 +50,16 @@ Then enable the `omniauth` feature and register providers in your Rodauth config
|
|
46
50
|
$ bundle add omniauth-facebook omniauth-twitter, omniauth-google-oauth2
|
47
51
|
```
|
48
52
|
```rb
|
49
|
-
|
50
|
-
|
53
|
+
# in your Rodauth configuration
|
54
|
+
enable :omniauth
|
51
55
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
+
omniauth_provider :facebook, ENV["FACEBOOK_APP_ID"], ENV["FACEBOOK_APP_SECRET"], scope: "email"
|
57
|
+
omniauth_provider :twitter, ENV["TWITTER_API_KEY"], ENV["TWITTER_API_SECRET"]
|
58
|
+
omniauth_provider :google_oauth2, ENV["GOOGLE_CLIENT_ID"], ENV["GOOGLE_CLIENT_SECRET"], name: :google
|
56
59
|
```
|
57
60
|
|
58
|
-
> [!
|
59
|
-
>
|
61
|
+
> [!WARNING]
|
62
|
+
> The `rodauth-omniauth` gem requires OmniAuth 2.x, so it's only compatible with providers gems that support it.
|
60
63
|
|
61
64
|
You can now add authentication links to your login form:
|
62
65
|
|
@@ -88,6 +91,24 @@ account.identities #=> [#<Account::Identity ...>, ...]
|
|
88
91
|
|
89
92
|
Currently, provider login is required to return the user's email address, and account creation is assumed not to require additional fields that need to be entered manually. There is currently also no built-in functionality for connecting/removing external identities when signed in. Both features are planned for future versions.
|
90
93
|
|
94
|
+
### Timestamps
|
95
|
+
|
96
|
+
If you want to know when an external identity was used first or last, you may want to add timestamp columns to the identities table:
|
97
|
+
|
98
|
+
```rb
|
99
|
+
create_table :account_identities do |t|
|
100
|
+
# ...
|
101
|
+
t.timestamps
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
In that case, you'll need to make sure the column values are populated on create/update:
|
106
|
+
|
107
|
+
```rb
|
108
|
+
omniauth_identity_insert_hash { super().merge(created_at: Time.now) }
|
109
|
+
omniauth_identity_update_hash { { updated_at: Time.now } }
|
110
|
+
```
|
111
|
+
|
91
112
|
### Login
|
92
113
|
|
93
114
|
After provider login, you can perform custom logic at the start of the callback request:
|
@@ -148,6 +169,31 @@ rodauth.omniauth_request_path(:google, action: "login") #=> "/auth/github?action
|
|
148
169
|
omniauth_create_account? { omniauth_params["action"] != "login" }
|
149
170
|
```
|
150
171
|
|
172
|
+
You can change the default error message for when existing account wasn't found in case automatic account creation is disabled:
|
173
|
+
|
174
|
+
```rb
|
175
|
+
omniauth_login_no_matching_account_error_flash "No existing account found"
|
176
|
+
```
|
177
|
+
|
178
|
+
### Multifactor authentication
|
179
|
+
|
180
|
+
By default, OmniAuth login will count only as one factor. So, if the user has multifactor authentication enabled, they will be asked to authenticate with 2nd factor when required.
|
181
|
+
|
182
|
+
If you're using OmniAuth login for SSO and want to rely on 2FA policies set on the external provider, you can have OmniAuth login count as two factors:
|
183
|
+
|
184
|
+
```rb
|
185
|
+
omniauth_two_factors? true
|
186
|
+
```
|
187
|
+
|
188
|
+
You can also make it conditional based on data from the external provider:
|
189
|
+
|
190
|
+
```rb
|
191
|
+
omniauth_two_factors? do
|
192
|
+
# only count as two factors if external account uses 2FA
|
193
|
+
omniauth_extra["raw_info"]["two_factor_authentication"]
|
194
|
+
end
|
195
|
+
```
|
196
|
+
|
151
197
|
### Identity data
|
152
198
|
|
153
199
|
You can also store extra data on the external identities. For example, we could override the update hash to store `info`, `credentials`, and `extra` data from the auth hash into separate columns:
|
@@ -193,23 +239,37 @@ omniauth_identities_provider_column :provider
|
|
193
239
|
omniauth_identities_uid_column :uid
|
194
240
|
```
|
195
241
|
|
196
|
-
|
242
|
+
### Audit logging
|
197
243
|
|
198
|
-
|
244
|
+
If you're using the [audit_logging] feature, it can be useful to include the external provider name in the `login` audit logs:
|
199
245
|
|
200
246
|
```rb
|
201
|
-
|
202
|
-
enable :omniauth_base
|
247
|
+
enable :audit_logging
|
203
248
|
|
204
|
-
|
205
|
-
|
249
|
+
audit_log_metadata_for :login do
|
250
|
+
{ "provider" => omniauth_provider } if authenticated_by.include?("omniauth")
|
206
251
|
end
|
252
|
+
```
|
253
|
+
|
254
|
+
## Base
|
207
255
|
|
208
|
-
|
209
|
-
|
256
|
+
The `omniauth` feature builds on top of the `omniauth_base` feature, which sets up OmniAuth and routes its requests, but has no interaction with the database. So, if you would prefer to handle external logins differently, you can load just the `omniauth_base` feature, and implement your own callback phase.
|
257
|
+
|
258
|
+
```rb
|
259
|
+
# in your Rodauth configuration
|
260
|
+
enable :omniauth_base
|
210
261
|
|
211
|
-
|
212
|
-
|
262
|
+
omniauth_provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user"
|
263
|
+
omniauth_provider :apple, ENV["APPLE_CLIENT_ID"], ENV["APPLE_CLIENT_SECRET"], scope: "email name"
|
264
|
+
```
|
265
|
+
```rb
|
266
|
+
# in your routes
|
267
|
+
get "/auth/:provider/callback", to: "rodauth#omniauth_login"
|
268
|
+
```
|
269
|
+
```rb
|
270
|
+
class RodauthController < ApplicationController
|
271
|
+
def omniauth_login
|
272
|
+
# ...
|
213
273
|
end
|
214
274
|
end
|
215
275
|
```
|
@@ -307,10 +367,6 @@ omniauth_on_failure do
|
|
307
367
|
end
|
308
368
|
```
|
309
369
|
|
310
|
-
#### CSRF protection
|
311
|
-
|
312
|
-
The default request validation phase uses Rodauth's configured CSRF protection, so there is no need for external gems such as `omniauth-rails_csrf_protection`.
|
313
|
-
|
314
370
|
### Inheritance
|
315
371
|
|
316
372
|
The registered providers are inherited between Rodauth auth classes, so you can have fine-grained configuration for different account types.
|
@@ -322,15 +378,13 @@ class RodauthBase < Rodauth::Auth
|
|
322
378
|
omniauth_provider :google_oauth2, ...
|
323
379
|
end
|
324
380
|
end
|
325
|
-
|
326
|
-
```rb
|
381
|
+
|
327
382
|
class RodauthMain < RodauthBase
|
328
383
|
configure do
|
329
384
|
omniauth_provider :facebook, ...
|
330
385
|
end
|
331
386
|
end
|
332
|
-
|
333
|
-
```rb
|
387
|
+
|
334
388
|
class RodauthAdmin < RodauthBase
|
335
389
|
configure do
|
336
390
|
omniauth_provider :twitter, ...
|
@@ -339,12 +393,6 @@ class RodauthAdmin < RodauthBase
|
|
339
393
|
end
|
340
394
|
```
|
341
395
|
```rb
|
342
|
-
class RodauthApp < Roda
|
343
|
-
plugin :rodauth, auth_class: RodauthMain
|
344
|
-
plugin :rodauth, auth_class: RodauthAdmin, name: :admin
|
345
|
-
end
|
346
|
-
```
|
347
|
-
```rb
|
348
396
|
rodauth.omniauth_providers #=> [:google_oauth2, :facebook]
|
349
397
|
rodauth(:admin).omniauth_providers #=> [:google_oauth2, :twitter, :github]
|
350
398
|
```
|
@@ -379,6 +427,9 @@ Content-Type: application/json
|
|
379
427
|
{ "success": "You have been logged in" }
|
380
428
|
```
|
381
429
|
|
430
|
+
> [!NOTE]
|
431
|
+
> Unless you're using JWT, make sure you're persisting cookies across requests, as most OmniAuth strategies rely on session storage.
|
432
|
+
|
382
433
|
If there was an OmniAuth failure, the error type will be included in the response:
|
383
434
|
|
384
435
|
```http
|
@@ -432,3 +483,4 @@ Everyone interacting in the rodauth-omniauth project's codebases, issue trackers
|
|
432
483
|
[rodauth-model]: https://github.com/janko/rodauth-model
|
433
484
|
[rodauth-rails]: https://github.com/janko/rodauth-rails
|
434
485
|
[omniauth-oauth2]: https://github.com/omniauth/omniauth-oauth2
|
486
|
+
[audit_logging]: https://rodauth.jeremyevans.net/rdoc/files/doc/audit_logging_rdoc.html
|
@@ -20,6 +20,7 @@ module Rodauth
|
|
20
20
|
auth_value_method :omniauth_identities_account_id_column, :account_id
|
21
21
|
auth_value_method :omniauth_identities_provider_column, :provider
|
22
22
|
auth_value_method :omniauth_identities_uid_column, :uid
|
23
|
+
auth_value_method :omniauth_two_factors?, false
|
23
24
|
|
24
25
|
auth_value_methods(
|
25
26
|
:omniauth_verify_account?,
|
@@ -97,7 +98,9 @@ module Rodauth
|
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
100
|
-
login("omniauth")
|
101
|
+
login("omniauth") do
|
102
|
+
two_factor_update_session("omniauth-two") if omniauth_second_factor?
|
103
|
+
end
|
101
104
|
end
|
102
105
|
|
103
106
|
def retrieve_omniauth_identity
|
@@ -126,7 +129,7 @@ module Rodauth
|
|
126
129
|
|
127
130
|
def possible_authentication_methods
|
128
131
|
methods = super
|
129
|
-
methods << "omniauth" unless methods.include?("password") || omniauth_account_identities_ds.empty?
|
132
|
+
methods << "omniauth" unless methods.include?("password") || (features.include?(:email_auth) && allow_email_auth?) || omniauth_account_identities_ds.empty?
|
130
133
|
methods
|
131
134
|
end
|
132
135
|
|
@@ -142,12 +145,12 @@ module Rodauth
|
|
142
145
|
remove_omniauth_identities
|
143
146
|
end
|
144
147
|
|
145
|
-
def allow_email_auth?
|
146
|
-
(defined?(super) ? super : true) && omniauth_account_identities_ds.empty?
|
147
|
-
end
|
148
|
-
|
149
148
|
attr_reader :omniauth_identity
|
150
149
|
|
150
|
+
def omniauth_second_factor?
|
151
|
+
features.include?(:two_factor_base) && uses_two_factor_authentication? && omniauth_two_factors?
|
152
|
+
end
|
153
|
+
|
151
154
|
def omniauth_verify_account?
|
152
155
|
features.include?(:verify_account) && account[login_column] == omniauth_email
|
153
156
|
end
|
@@ -209,7 +212,7 @@ module Rodauth
|
|
209
212
|
end
|
210
213
|
|
211
214
|
def _account_from_omniauth_identity
|
212
|
-
|
215
|
+
_account_from_id(omniauth_identity_account_id)
|
213
216
|
end
|
214
217
|
|
215
218
|
def omniauth_identity_id
|
data/rodauth-omniauth.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "rodauth-omniauth"
|
3
|
-
spec.version = "0.
|
3
|
+
spec.version = "0.6.0"
|
4
4
|
spec.authors = ["Janko Marohnić"]
|
5
5
|
spec.email = ["janko@hey.com"]
|
6
6
|
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.files = Dir["README.md", "LICENSE.txt", "*.gemspec", "lib/**/*", "locales/**/*"]
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "rodauth", "~> 2.
|
20
|
+
spec.add_dependency "rodauth", "~> 2.36"
|
21
21
|
spec.add_dependency "omniauth", "~> 2.0"
|
22
22
|
|
23
23
|
spec.add_development_dependency "minitest"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rodauth-omniauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janko Marohnić
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rodauth
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.36'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.36'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: omniauth
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
212
|
- !ruby/object:Gem::Version
|
213
213
|
version: '0'
|
214
214
|
requirements: []
|
215
|
-
rubygems_version: 3.5.
|
215
|
+
rubygems_version: 3.5.23
|
216
216
|
signing_key:
|
217
217
|
specification_version: 4
|
218
218
|
summary: Rodauth extension for logging in and creating account via OmniAuth authentication.
|