rodauth-omniauth 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +62 -35
- data/lib/rodauth/features/omniauth.rb +9 -2
- 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
|
|
@@ -90,7 +93,16 @@ Currently, provider login is required to return the user's email address, and ac
|
|
90
93
|
|
91
94
|
### Timestamps
|
92
95
|
|
93
|
-
If you
|
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:
|
94
106
|
|
95
107
|
```rb
|
96
108
|
omniauth_identity_insert_hash { super().merge(created_at: Time.now) }
|
@@ -163,6 +175,25 @@ You can change the default error message for when existing account wasn't found
|
|
163
175
|
omniauth_login_no_matching_account_error_flash "No existing account found"
|
164
176
|
```
|
165
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
|
+
|
166
197
|
### Identity data
|
167
198
|
|
168
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:
|
@@ -210,9 +241,11 @@ omniauth_identities_uid_column :uid
|
|
210
241
|
|
211
242
|
### Audit logging
|
212
243
|
|
213
|
-
If you're using the
|
244
|
+
If you're using the [audit_logging] feature, it can be useful to include the external provider name in the `login` audit logs:
|
214
245
|
|
215
246
|
```rb
|
247
|
+
enable :audit_logging
|
248
|
+
|
216
249
|
audit_log_metadata_for :login do
|
217
250
|
{ "provider" => omniauth_provider } if authenticated_by.include?("omniauth")
|
218
251
|
end
|
@@ -223,18 +256,20 @@ end
|
|
223
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.
|
224
257
|
|
225
258
|
```rb
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
omniauth_provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user"
|
230
|
-
omniauth_provider :apple, ENV["APPLE_CLIENT_ID"], ENV["APPLE_CLIENT_SECRET"], scope: "email name"
|
231
|
-
end
|
259
|
+
# in your Rodauth configuration
|
260
|
+
enable :omniauth_base
|
232
261
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
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
|
+
# ...
|
238
273
|
end
|
239
274
|
end
|
240
275
|
```
|
@@ -332,10 +367,6 @@ omniauth_on_failure do
|
|
332
367
|
end
|
333
368
|
```
|
334
369
|
|
335
|
-
#### CSRF protection
|
336
|
-
|
337
|
-
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`.
|
338
|
-
|
339
370
|
### Inheritance
|
340
371
|
|
341
372
|
The registered providers are inherited between Rodauth auth classes, so you can have fine-grained configuration for different account types.
|
@@ -347,15 +378,13 @@ class RodauthBase < Rodauth::Auth
|
|
347
378
|
omniauth_provider :google_oauth2, ...
|
348
379
|
end
|
349
380
|
end
|
350
|
-
|
351
|
-
```rb
|
381
|
+
|
352
382
|
class RodauthMain < RodauthBase
|
353
383
|
configure do
|
354
384
|
omniauth_provider :facebook, ...
|
355
385
|
end
|
356
386
|
end
|
357
|
-
|
358
|
-
```rb
|
387
|
+
|
359
388
|
class RodauthAdmin < RodauthBase
|
360
389
|
configure do
|
361
390
|
omniauth_provider :twitter, ...
|
@@ -364,12 +393,6 @@ class RodauthAdmin < RodauthBase
|
|
364
393
|
end
|
365
394
|
```
|
366
395
|
```rb
|
367
|
-
class RodauthApp < Roda
|
368
|
-
plugin :rodauth, auth_class: RodauthMain
|
369
|
-
plugin :rodauth, auth_class: RodauthAdmin, name: :admin
|
370
|
-
end
|
371
|
-
```
|
372
|
-
```rb
|
373
396
|
rodauth.omniauth_providers #=> [:google_oauth2, :facebook]
|
374
397
|
rodauth(:admin).omniauth_providers #=> [:google_oauth2, :twitter, :github]
|
375
398
|
```
|
@@ -404,6 +427,9 @@ Content-Type: application/json
|
|
404
427
|
{ "success": "You have been logged in" }
|
405
428
|
```
|
406
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
|
+
|
407
433
|
If there was an OmniAuth failure, the error type will be included in the response:
|
408
434
|
|
409
435
|
```http
|
@@ -457,3 +483,4 @@ Everyone interacting in the rodauth-omniauth project's codebases, issue trackers
|
|
457
483
|
[rodauth-model]: https://github.com/janko/rodauth-model
|
458
484
|
[rodauth-rails]: https://github.com/janko/rodauth-rails
|
459
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
|
@@ -144,6 +147,10 @@ module Rodauth
|
|
144
147
|
|
145
148
|
attr_reader :omniauth_identity
|
146
149
|
|
150
|
+
def omniauth_second_factor?
|
151
|
+
features.include?(:two_factor_base) && uses_two_factor_authentication? && omniauth_two_factors?
|
152
|
+
end
|
153
|
+
|
147
154
|
def omniauth_verify_account?
|
148
155
|
features.include?(:verify_account) && account[login_column] == omniauth_email
|
149
156
|
end
|
@@ -205,7 +212,7 @@ module Rodauth
|
|
205
212
|
end
|
206
213
|
|
207
214
|
def _account_from_omniauth_identity
|
208
|
-
|
215
|
+
_account_from_id(omniauth_identity_account_id)
|
209
216
|
end
|
210
217
|
|
211
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.
|