diff --git a/README.md b/README.md index 7818021..fb2c3eb 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,8 @@ end ### Example (Web with PKCE) +Proof Key for Code Exchange (PKCE) is an [RFC](https://www.rfc-editor.org/rfc/rfc7636) that aims to prevent malicious operating system processes from hijacking an OAUTH 2.0 exchange. PKCE mitigates the above vulnerability by including `code_challenge` and `code_challenge_method` parameters in the Authorization Request and a `code_verifier` parameter in the Access Token Request. + ```ruby require 'googleauth' require 'googleauth/web_user_authorizer' @@ -118,7 +120,6 @@ get('/authorize') do # User needs to take care of generating the code_verifier and storing it in # the session. request.session['code_verifier'] ||= authorizer.generate_code_verifier - authorizer.code_verifier = request.session['code_verifier'] credentials = authorizer.get_credentials(user_id, request) if credentials.nil? redirect authorizer.get_authorization_url(login_hint: user_id, request: request) diff --git a/lib/googleauth/user_authorizer.rb b/lib/googleauth/user_authorizer.rb index e1664f8..3150b95 100644 --- a/lib/googleauth/user_authorizer.rb +++ b/lib/googleauth/user_authorizer.rb @@ -60,9 +60,9 @@ class UserAuthorizer # Defaults to '/oauth2callback' # @param [String] code_verifier # Random string of 43-128 chars used to verify the key exchange using - # PKCE. Auto-generated if not provided + # PKCE. def initialize client_id, scope, token_store, - callback_uri = nil, code_verifier = nil + callback_uri = nil, code_verifier: nil raise NIL_CLIENT_ID_ERROR if client_id.nil? raise NIL_SCOPE_ERROR if scope.nil? @@ -261,8 +261,7 @@ def code_verifier= new_code_verifier # Generate the code verifier needed to be sent while fetching # authorization URL. def generate_code_verifier - random_number = rand 32..96 - SecureRandom.alphanumeric(random_number).to_str + @code_verifier ||= SecureRandom.alphanumeric(rand(32..96)) end private diff --git a/lib/googleauth/web_user_authorizer.rb b/lib/googleauth/web_user_authorizer.rb index 76484d9..ddf9644 100644 --- a/lib/googleauth/web_user_authorizer.rb +++ b/lib/googleauth/web_user_authorizer.rb @@ -98,10 +98,10 @@ def self.handle_auth_callback_deferred request # to '/oauth2callback' # @param [String] code_verifier # Random string of 43-128 chars used to verify the key exchange using - # PKCE. Auto-generated if not provided. + # PKCE. def initialize client_id, scope, token_store, - callback_uri = nil, code_verifier = nil - super client_id, scope, token_store, callback_uri, code_verifier + callback_uri = nil, code_verifier: nil + super client_id, scope, token_store, callback_uri, code_verifier: code_verifier end # Handle the result of the oauth callback. Exchanges the authorization diff --git a/spec/googleauth/user_authorizer_spec.rb b/spec/googleauth/user_authorizer_spec.rb index 894f7da..2a176ae 100644 --- a/spec/googleauth/user_authorizer_spec.rb +++ b/spec/googleauth/user_authorizer_spec.rb @@ -105,7 +105,7 @@ scope, token_store, callback_uri, - code_verifier) + code_verifier: code_verifier) end let :uri do authorizer.get_authorization_url diff --git a/spec/googleauth/web_user_authorizer_spec.rb b/spec/googleauth/web_user_authorizer_spec.rb index 0ace46b..2e07d9c 100644 --- a/spec/googleauth/web_user_authorizer_spec.rb +++ b/spec/googleauth/web_user_authorizer_spec.rb @@ -90,7 +90,7 @@ end it "should include code_challenge and code_challenge_method" do - authorizer.code_verifier = authorizer.generate_code_verifier + authorizer.generate_code_verifier url = authorizer.get_authorization_url(request: request) expect(url).to match(/code_challenge=/) expect(url).to match(/code_challenge_method=S256/)