Last active
September 14, 2023 13:57
-
-
Save bradgessler/ba061c02c8cc3bf21a32e157241d1478 to your computer and use it in GitHub Desktop.
OAuth Google controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OAuth::GoogleAuthorizationsController < ApplicationController | |
CLIENT_ID = Rails.application.credentials.google.client_id | |
CLIENT_SECRET = Rails.application.credentials.google.client_secret | |
SCOPE = "openid email profile" | |
AUTHORIZATION_URL = URI("https://accounts.google.com/o/oauth2/v2/auth") | |
TOKEN_URL = URI("https://www.googleapis.com/oauth2/v4/token") | |
USER_INFO_URL = URI("https://www.googleapis.com/oauth2/v3/userinfo") | |
before_action :validate_state_token, only: :show | |
def create | |
redirect_to authorization_url.to_s, allow_other_host: true | |
end | |
def show | |
access_token = request_access_token.parse.fetch("access_token") | |
user_info = request_user_info(access_token: access_token).parse | |
user = User.find_or_create_by(email: user_info.fetch("email")) | |
user ||= user_info.fetch("name") | |
self.current_user = user | |
redirect_to root_url | |
end | |
private | |
def validate_state_token | |
state_token = params.fetch(:state) | |
unless valid_authenticity_token?(session, state_token) | |
raise ActionController::InvalidAuthenticityToken, "The state=#{state_token} token is inauthentic." | |
end | |
end | |
# Generates the OAuth authorization URL that will redirect the user to the OAuth provider. | |
# A Rails `form_authenticity_token` is used as the `state` parameter to prevent CSRF. The | |
# `callback_url` is where the user is sent back to after authenticating with the OAuth provider. | |
def authorization_url | |
AUTHORIZATION_URL.build.query( | |
client_id: CLIENT_ID, | |
redirect_uri: callback_url, | |
response_type: "code", | |
scope: SCOPE, | |
state: form_authenticity_token | |
) | |
end | |
# Requests an OAuth access token from the OAuth provider. The access token is used for subsequent | |
# requests to gather information like a users name, email, address, or whatever other information | |
# The OAuth provider makes available. | |
def request_access_token | |
HTTP.post(TOKEN_URL, form: { | |
client_id: CLIENT_ID, | |
client_secret: CLIENT_SECRET, | |
code: params.fetch(:code), | |
grant_type: "authorization_code", | |
redirect_uri: callback_url | |
}) | |
end | |
def request_user_info(access_token:) | |
HTTP.auth("Bearer #{access_token}").get(USER_INFO_URL) | |
end | |
# The URL the OAuth provider will redirect the user back to after authenticating. | |
def callback_url | |
url_for(action: :show, only_path: false) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment