diff --git a/common/djangoapps/third_party_auth/pipeline.py b/common/djangoapps/third_party_auth/pipeline.py
index b4a683e9b5f395aef06f93ce5d3df4a7343d6a6c..c3a17d642fbbb62abf7226a72dcdc3b66be04d1c 100644
--- a/common/djangoapps/third_party_auth/pipeline.py
+++ b/common/djangoapps/third_party_auth/pipeline.py
@@ -209,6 +209,11 @@ def get(request):
     """Gets the running pipeline's data from the passed request."""
     strategy = social_django.utils.load_strategy(request)
     token = strategy.session_get('partial_pipeline_token')
+
+    if not token:
+        strategy.session_set('partial_pipeline_token', strategy.session_get('partial_pipeline_token_'))
+        token = strategy.session_get('partial_pipeline_token')
+
     partial_object = strategy.partial_load(token)
     pipeline_data = None
     if partial_object:
@@ -560,6 +565,10 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
         return (current_provider and
                 current_provider.slug in [saml_provider.slug for saml_provider in saml_providers_list])
 
+    if current_partial:
+        strategy.session_set('partial_pipeline_token_', current_partial.token)
+        strategy.storage.partial.store(current_partial)
+
     if not user:
         # Use only email for user existence check in case of saml provider
         if is_provider_saml():
diff --git a/common/djangoapps/third_party_auth/tests/specs/base.py b/common/djangoapps/third_party_auth/tests/specs/base.py
index f29099308d0739392704b54472d81f2435a3e3dd..73521de0f5617730b26c1641bb2d6582a2961fc3 100644
--- a/common/djangoapps/third_party_auth/tests/specs/base.py
+++ b/common/djangoapps/third_party_auth/tests/specs/base.py
@@ -542,6 +542,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
         request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
         request.user = self.create_user_models_for_existing_account(
             strategy, 'user@example.com', 'password', self.get_username(), skip_social_auth=True)
+        partial_pipeline_token = strategy.session_get('partial_pipeline_token')
+        partial_data = strategy.storage.partial.load(partial_pipeline_token)
 
         # Instrument the pipeline to get to the dashboard with the full
         # expected state.
@@ -561,24 +563,14 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
 
         # We should be redirected back to the complete page, setting
         # the "logged in" cookie for the marketing site.
-        self.assert_logged_in_cookie_redirect(actions.do_complete(
-            request.backend, social_views._do_login, request.user, None,  # pylint: disable=protected-access
-            redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request
-        ))
+        self.assert_logged_in_cookie_redirect(self.do_complete(strategy, request, partial_pipeline_token, partial_data))
 
         # Set the cookie and try again
         self.set_logged_in_cookies(request)
 
         # Fire off the auth pipeline to link.
         self.assert_redirect_after_pipeline_completes(
-            actions.do_complete(
-                request.backend,
-                social_views._do_login,  # pylint: disable=protected-access
-                request.user,
-                None,
-                redirect_field_name=auth.REDIRECT_FIELD_NAME,
-                request=request
-            )
+            self.do_complete(strategy, request, partial_pipeline_token, partial_data)
         )
 
         # Now we expect to be in the linked state, with a backend entry.
@@ -694,6 +686,9 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
         strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
         user = self.create_user_models_for_existing_account(
             strategy, 'user@example.com', 'password', self.get_username())
+        partial_pipeline_token = strategy.session_get('partial_pipeline_token')
+        partial_data = strategy.storage.partial.load(partial_pipeline_token)
+
         self.assert_social_auth_exists_for_user(user, strategy)
         self.assertTrue(user.is_active)
 
@@ -734,7 +729,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
         self.set_logged_in_cookies(request)
 
         self.assert_redirect_after_pipeline_completes(
-            actions.do_complete(request.backend, social_views._do_login, user=user, request=request))
+            self.do_complete(strategy, request, partial_pipeline_token, partial_data, user)
+        )
         self.assert_account_settings_context_looks_correct(account_settings_context(request))
 
     def test_signin_fails_if_account_not_active(self):
@@ -793,6 +789,8 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
         request, strategy = self.get_request_and_strategy(
             auth_entry=pipeline.AUTH_ENTRY_REGISTER, redirect_uri='social:complete')
         strategy.request.backend.auth_complete = mock.MagicMock(return_value=self.fake_auth_complete(strategy))
+        partial_pipeline_token = strategy.session_get('partial_pipeline_token')
+        partial_data = strategy.storage.partial.load(partial_pipeline_token)
 
         # Begin! Grab the registration page and check the login control on it.
         self.assert_register_response_before_pipeline_looks_correct(self.client.get('/register'))
@@ -846,15 +844,13 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
 
         # We should be redirected back to the complete page, setting
         # the "logged in" cookie for the marketing site.
-        self.assert_logged_in_cookie_redirect(actions.do_complete(
-            request.backend, social_views._do_login, request.user, None,  # pylint: disable=protected-access
-            redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request
-        ))
+        self.assert_logged_in_cookie_redirect(self.do_complete(strategy, request, partial_pipeline_token, partial_data))
 
         # Set the cookie and try again
         self.set_logged_in_cookies(request)
         self.assert_redirect_after_pipeline_completes(
-            actions.do_complete(strategy.request.backend, social_views._do_login, user=created_user, request=request))
+            self.do_complete(strategy, request, partial_pipeline_token, partial_data, created_user)
+        )
         # Now the user has been redirected to the dashboard. Their third party account should now be linked.
         self.assert_social_auth_exists_for_user(created_user, strategy)
         self.assert_account_settings_context_looks_correct(account_settings_context(request), linked=True)
@@ -974,6 +970,19 @@ class IntegrationTest(testutil.TestCase, test.TestCase, HelperMixin):
         """
         raise NotImplementedError
 
+    def do_complete(self, strategy, request, partial_pipeline_token, partial_data, user=None):
+        """
+        Makes sure that strategy store includes the partial data object before
+        calling actions.do_complete
+        """
+        strategy.storage.partial.store(partial_data)
+        if not user:
+            user = request.user
+        return actions.do_complete(
+            request.backend, social_views._do_login, user, None,  # pylint: disable=protected-access
+            redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request, partial_token=partial_pipeline_token
+        )
+
 
 # pylint: disable=abstract-method
 @django_utils.override_settings(ECOMMERCE_API_URL=TEST_API_URL)
diff --git a/common/djangoapps/third_party_auth/tests/specs/test_linkedin.py b/common/djangoapps/third_party_auth/tests/specs/test_linkedin.py
index ac4f47d895a95e06a375db16573435e3681536bc..091471657d3cefa4d55d5e5b9b711a000673aa85 100644
--- a/common/djangoapps/third_party_auth/tests/specs/test_linkedin.py
+++ b/common/djangoapps/third_party_auth/tests/specs/test_linkedin.py
@@ -4,6 +4,15 @@ from __future__ import absolute_import
 from third_party_auth.tests.specs import base
 
 
+def get_localized_name(name):
+    """Returns the localizedName from the name object"""
+    locale = "{}_{}".format(
+        name["preferredLocale"]["language"],
+        name["preferredLocale"]["country"]
+    )
+    return name['localized'].get(locale, '')
+
+
 class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest):
     """Integration tests for provider.LinkedInOauth2."""
 
@@ -21,11 +30,29 @@ class LinkedInOauth2IntegrationTest(base.Oauth2IntegrationTest):
         'expires_in': 'expires_in_value',
     }
     USER_RESPONSE_DATA = {
-        'lastName': 'lastName_value',
+        'lastName': {
+            "localized": {
+                "en_US": "Doe"
+            },
+            "preferredLocale": {
+                "country": "US",
+                "language": "en"
+            }
+        },
         'id': 'id_value',
-        'firstName': 'firstName_value',
+        'firstName': {
+            "localized": {
+                "en_US": "Doe"
+            },
+            "preferredLocale": {
+                "country": "US",
+                "language": "en"
+            }
+        },
     }
 
     def get_username(self):
         response_data = self.get_response_data()
-        return response_data.get('firstName') + response_data.get('lastName')
+        first_name = get_localized_name(response_data.get('firstName'))
+        last_name = get_localized_name(response_data.get('lastName'))
+        return first_name + last_name
diff --git a/common/djangoapps/third_party_auth/tests/utils.py b/common/djangoapps/third_party_auth/tests/utils.py
index 8fe9ee136a44d91a679413665b2f99187ba089bc..47b8bb51736bcb1d5c97e2b03a4484ff8fa94e60 100644
--- a/common/djangoapps/third_party_auth/tests/utils.py
+++ b/common/djangoapps/third_party_auth/tests/utils.py
@@ -98,7 +98,7 @@ class ThirdPartyOAuthTestMixinFacebook(object):
 class ThirdPartyOAuthTestMixinGoogle(object):
     """Tests oauth with the Google backend"""
     BACKEND = "google-oauth2"
-    USER_URL = "https://www.googleapis.com/plus/v1/people/me"
+    USER_URL = "https://www.googleapis.com/oauth2/v3/userinfo"
     # In google-oauth2 responses, the "email" field is used as the user's identifier
     UID_FIELD = "email"
 
diff --git a/requirements/edx/base.in b/requirements/edx/base.in
index fb89cec707b26a69bed2b63aca741a77c696e0bd..781ae4a5e4ba68e742275d8de1c7c0dd83d21843 100644
--- a/requirements/edx/base.in
+++ b/requirements/edx/base.in
@@ -133,8 +133,8 @@ pyuca==1.1                          # For more accurate sorting of translated co
 recommender-xblock                  # https://github.com/edx/RecommenderXBlock
 rest-condition                      # DRF's recommendation for supporting complex permissions
 rfc6266-parser                      # Used to generate Content-Disposition headers.
-social-auth-app-django<3.0.0
-social-auth-core<2.0.0
+social-auth-app-django==3.1.0
+social-auth-core==3.2.0
 pysrt                               # Support for SubRip subtitle files, used in the video XModule
 pytz                                # Time zone information database
 PyYAML                              # Used to parse XModule resource templates
diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt
index a2419357d729ea5d60c1f6e94764cbc4c128f733..4ab31d76b230c860a62d4b6c2543b6977961b57b 100644
--- a/requirements/edx/base.txt
+++ b/requirements/edx/base.txt
@@ -227,8 +227,8 @@ simplejson==3.17.0
 singledispatch==3.4.0.3
 six==1.13.0
 slumber==0.7.1            # via edx-bulk-grades, edx-enterprise, edx-rest-api-client
-social-auth-app-django==2.1.0
-social-auth-core==1.7.0
+social-auth-app-django==3.1.0
+social-auth-core==3.2.0
 sorl-thumbnail==12.3
 sortedcontainers==2.1.0
 soupsieve==1.9.5          # via beautifulsoup4
diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt
index 151a45b3670984f408f697665471a73142275557..9007b65d3f0968bbaef7ab20a827c5bcd53764e6 100644
--- a/requirements/edx/development.txt
+++ b/requirements/edx/development.txt
@@ -305,8 +305,8 @@ singledispatch==3.4.0.3
 six==1.13.0
 slumber==0.7.1
 snowballstemmer==2.0.0    # via sphinx
-social-auth-app-django==2.1.0
-social-auth-core==1.7.0
+social-auth-app-django==3.1.0
+social-auth-core==3.2.0
 sorl-thumbnail==12.3
 sortedcontainers==2.1.0
 soupsieve==1.9.5
diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt
index d9dea4233ae6bfff93233154f1eb275adb7d8022..70e3d991ebd3b8f11ea1561ad923839b4cefedbc 100644
--- a/requirements/edx/testing.txt
+++ b/requirements/edx/testing.txt
@@ -292,8 +292,8 @@ simplejson==3.17.0
 singledispatch==3.4.0.3
 six==1.13.0
 slumber==0.7.1
-social-auth-app-django==2.1.0
-social-auth-core==1.7.0
+social-auth-app-django==3.1.0
+social-auth-core==3.2.0
 sorl-thumbnail==12.3
 sortedcontainers==2.1.0
 soupsieve==1.9.5