docs: @Sensitive
      public Map<String, Object> getAccessToken(HttpServletRequest request, HttpServletResponse response, SocialLoginConfig config) {
          TwitterEndpointServices twitter = getTwitterEndpointServices();
          twitter.setConsumerKey(config.getClientId());
          twitter.setConsumerSecret(config.getClientSecret());
  
          Map<String, String[]> params = request.getParameterMap();
  
          if (isMissingParameter(params, TwitterConstants.TWITTER_ENDPOINT_ACCESS_TOKEN)) {
              return null;
          }
  
          // oauth_token provided in request MUST match the request token obtained earlier
          String token = request.getParameter(TwitterConstants.PARAM_OAUTH_TOKEN);
          String cachedRequestToken = webUtils.getAndClearCookie(request, response, TwitterConstants.COOKIE_NAME_REQUEST_TOKEN);
          if (tc.isDebugEnabled()) {
              Tr.debug(tc, "Obtained token from request: [" + token + "], matching against: [" + cachedRequestToken + "]");
          }
  
          if (!token.equals(cachedRequestToken)) {
              Tr.error(tc, "TWITTER_TOKEN_DOES_NOT_MATCH");
              return null;
          }
  
          String oauthVerifier = request.getParameter(TwitterConstants.PARAM_OAUTH_VERIFIER);
  
          Map<String, Object> result = twitter.obtainAccessToken(config, cachedRequestToken, oauthVerifier);
          if (result == null || result.isEmpty()) {
              Tr.error(tc, "TWITTER_ERROR_OBTAINING_ENDPOINT_RESULT", new Object[] { TwitterConstants.TWITTER_ENDPOINT_ACCESS_TOKEN });
              return null;
          }
  
          if (!isSuccessfulResult(result, TwitterConstants.TWITTER_ENDPOINT_ACCESS_TOKEN)) {
              return null;
          }
  
          // If result was successful, the result has already been verified to contain a non-empty access_token and access_token_secret
          return result;
      }