1
+ require "typhoeus"
2
+
1
3
class Oauth ::SorceryController < ApplicationController
2
4
def login
3
5
login_at ( params [ :provider ] )
4
6
end
5
7
6
8
def callback
7
- user = login_from ( params [ :provider ] , true ) || create_from ( params [ :provider ] )
9
+ provider = params [ :provider ]
10
+ auth = build_auth_hash ( provider )
11
+ user = User . where ( email : auth [ :email ] ) . first_or_initialize
12
+ user . save! unless user . persisted?
13
+
14
+ user . authentications . where ( provider :) . first_or_create! do |authentication |
15
+ authentication . uid = auth [ :uid ]
16
+ end
17
+
18
+ reset_session
8
19
store_user_data_in_session ( user )
9
20
redirect_to root_path
10
- rescue ActiveRecord ::RecordNotUnique
11
- redirect_to root_path , alert : "That email address has already been taken"
12
21
rescue StandardError => e
13
22
Sentry . capture_exception ( e )
14
- redirect_to root_path , alert : "Login via Google failed"
23
+ redirect_to root_path , alert : "Login with Google failed"
15
24
end
16
25
17
26
private
@@ -23,10 +32,6 @@ def store_user_data_in_session(user)
23
32
session [ :email ] = user . email
24
33
end
25
34
26
- def provider_title
27
- params [ :provider ] . titleize
28
- end
29
-
30
35
def jwt_for ( user )
31
36
JWT . encode (
32
37
{
@@ -37,4 +42,29 @@ def jwt_for(user)
37
42
"HS256"
38
43
)
39
44
end
45
+
46
+ def build_auth_hash ( provider )
47
+ response = Typhoeus . get \
48
+ "https://www.googleapis.com/oauth2/v2/userinfo" ,
49
+ headers : { Authorization : "Bearer #{ fetch_access_token } " }
50
+ data = JSON . parse ( response . body )
51
+ {
52
+ uid : data [ "id" ] ,
53
+ email : data [ "email" ]
54
+ }
55
+ end
56
+
57
+ def fetch_access_token
58
+ response = Typhoeus . post (
59
+ "https://oauth2.googleapis.com/token" ,
60
+ body : {
61
+ code : params [ :code ] ,
62
+ client_id : Rails . application . config . sorcery . google . key ,
63
+ client_secret : Rails . application . config . sorcery . google . secret ,
64
+ redirect_uri : Rails . application . config . sorcery . google . callback_url ,
65
+ grant_type : "authorization_code"
66
+ }
67
+ )
68
+ JSON . parse ( response . body ) [ "access_token" ]
69
+ end
40
70
end
0 commit comments