Skip to content

Commit ff2130c

Browse files
committed
Improve OAuth login
1 parent 07a2178 commit ff2130c

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed
+38-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
1+
require "typhoeus"
2+
13
class Oauth::SorceryController < ApplicationController
24
def login
35
login_at(params[:provider])
46
end
57

68
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
819
store_user_data_in_session(user)
920
redirect_to root_path
10-
rescue ActiveRecord::RecordNotUnique
11-
redirect_to root_path, alert: "That email address has already been taken"
1221
rescue StandardError => e
1322
Sentry.capture_exception(e)
14-
redirect_to root_path, alert: "Login via Google failed"
23+
redirect_to root_path, alert: "Login with Google failed"
1524
end
1625

1726
private
@@ -23,10 +32,6 @@ def store_user_data_in_session(user)
2332
session[:email] = user.email
2433
end
2534

26-
def provider_title
27-
params[:provider].titleize
28-
end
29-
3035
def jwt_for(user)
3136
JWT.encode(
3237
{
@@ -37,4 +42,29 @@ def jwt_for(user)
3742
"HS256"
3843
)
3944
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
4070
end

app/javascript/stylesheets/feedback.css.scss

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
font-size: 1.4rem;
1919
width: 20rem;
2020
animation: popOut 0.3s ease-in-out;
21+
overflow: hidden;
2122

2223
&.notice {
2324
background-color: $bg-blue;
@@ -44,6 +45,7 @@
4445
height: 4px;
4546
background-color: $header-gray;
4647
animation: progress 5s linear forwards;
48+
// margin: 0 -1rem -1rem -1rem;
4749
}
4850
}
4951

app/models/concerns/sorcery_authenticable.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ module SorceryAuthenticable
1111
presence: true,
1212
uniqueness: true,
1313
format: {
14-
with: /\A[A-Za-z0-9_]{4,15}\z/,
14+
with: /\A[A-Za-z0-9_]{3,15}\z/,
1515
message: "may contain only letters, numbers, and " \
1616
"underscores, must be unique, and must be " \
17-
"4 to 15 characters long"
17+
"3 to 15 characters long"
1818
}
1919
validates :email, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
2020
validates :password, length: { minimum: 5 }, if: :password
@@ -30,7 +30,7 @@ def assign_username_from_email
3030

3131
name = email.split("@").first.gsub(/[^A-Za-z0-9_]/, "_")
3232
name = "#{name.first(10)}_#{SecureRandom.hex(2)}" if User.where(username: name).exists?
33-
self.username = name
33+
self.username = name.first(15)
3434
end
3535
end
3636
end

0 commit comments

Comments
 (0)