【问题标题】:OAuth Request token = null in android appOAuth 请求令牌 = android 应用程序中的 null
【发布时间】:2011-06-29 03:18:00
【问题描述】:

我正在尝试使用 OAuth 对某些内容(在本例中为 LinkedIn)进行身份验证,但请求的令牌总是返回 null?

下面是我的代码:

public void authenticateAppOauthApi() {
        Log.d(TAG, "authenticateAppOauthApi");

        OAuthServiceProvider provider = new OAuthServiceProvider(
                REQUEST_TOKEN_PATH, AUTHORIZE_PATH, ACCESS_TOKEN_PATH);

        OAuthConsumer consumer = new OAuthConsumer(CALLBACK_URL, API_KEY,
                SECRET_KEY, provider);

        OAuthAccessor accessor = new OAuthAccessor(consumer);

        Intent intent = new Intent(Intent.ACTION_VIEW);
        Log.d(TAG, "Intent intent = new Intent(Intent.ACTION_VIEW );");
        // intent.setData(Uri.parse(url));
        String url = accessor.consumer.serviceProvider.userAuthorizationURL
                + "?oauth_token=" + accessor.requestToken + "&oauth_callback="
                + accessor.consumer.callbackURL;

        intent.setData(Uri.parse(url));
        Log.d(TAG, "intent.setData(Uri.parse(url)); = " + url);
        mContext.startActivity(intent);

        Log.d(TAG, "finish authenticateApp");
}

我基本上按照这里的例子http://donpark.org/blog/2009/01/24/android-client-side-oauth

提前致谢

【问题讨论】:

  • 嗨,有人有什么建议吗?谢谢

标签: android oauth


【解决方案1】:

你可以试试这个代码。

OAuthClient oAuthClient = new OAuthClient(new HttpClient4());
try {
 oAuthClient.getRequestToken(accessor);
} catch (IOException e) {
 e.printStackTrace();
} catch (OAuthException e) {
 e.printStackTrace();
} catch (URISyntaxException e) {
 e.printStackTrace();
}

【讨论】:

    【解决方案2】:

    只是一个想法,是 HTTP URL 还是 HTTPS URL?

    我在访问 HTTPS URL 时遇到问题,浏览器和应用程序告诉我证书错误。

    Android 不知道某些根证书。

    【讨论】:

    • 是的,它是一个 HTTPS 网址,但它没有告诉我任何有关证书的信息。由于请求令牌为空,它只是启动浏览器并加载身份验证页面时出错。我发现的示例都使用旧的 Signpost 1.1,但是当您转到 Signpost code.google.com/p/oauth-signpost/downloads/list 时,它的 1.2 和前面示例中使用的许多对象都不起作用。
    【解决方案3】:

    在我的 Scala Android 应用程序中使用我在网上找到的一个 OAuth 库时遇到了一些问题。我没有找到使用 lib 的方法,而是自己推出了...不确定它是否适用于linkedin(它适用于使用 HTTPS 的 Yammer)。好吧,下面是相关代码,请注意,我对 Android 和 Scala 都很陌生,所以可能有更好的方法来实现这一点。

    布局文件“R.layout.authorization”非常基本,包含两个按钮和一个相对布局中的文本字段。

    class Authorization extends Activity {
    
      val client = new DefaultHttpClient()
      val reqUrl = "https://www.yammer.com/oauth/request_token"
      val authUrl = "https://www.yammer.com/oauth/authorize?oauth_token="
      val accessUrl = "https://www.yammer.com/oauth/access_token"
    
      override def onCreate(bundle:Bundle) = {
        super.onCreate(bundle)
        this.setContentView(R.layout.authorization)
    
        val authButton = findViewById(R.id.authButton).asInstanceOf[Button]
        val getCodeButton = findViewById(R.id.getCode).asInstanceOf[Button]
    
        val prefs = getSharedPreferences(PreferenceFile(), 0)
        if(prefs.contains("oauth_request_token")) { 
          authButton.setVisibility(View.VISIBLE)
        }
    
        setupListeners(authButton, getCodeButton) 
      }
    
      private def getAuthVerifier() = { 
        val authVerifierBox:EditText = Authorization.this.findViewById(R.id.authVerifier).asInstanceOf[EditText]
        if(authVerifierBox != null && authVerifierBox.getText() != null) {
          authVerifierBox.getText().toString()    
        } else {
          ""
        }
      }
    
      private def setupListeners(authButton:Button, getCodeButton:Button) = {
        authButton.setOnClickListener(new View.OnClickListener() {
          override def onClick(view:View) = {
            retrieveAuthTokenAndSecret()  
          }
        })
        getCodeButton.setOnClickListener(new View.OnClickListener() {
          override def onClick(view:View) = {
            try {
              // Retrieve a request token with an async task and then start the browser...
              // Use of an implicit definition to convert tuple to an async task.
              (() => {
                  // Task to perform
                  val reqPost = new HttpPost(reqUrl)
                  reqPost.setHeader("Authorization", OAuthHeaderBuilder(null,null,null))
                  reqPost.setHeader("Content-Type", "application/x-www-form-urlencoded")
                  val reqResp= client.execute(reqPost)
                  reqResp.getEntity()
              },  
               (entity:HttpEntity) => {
                // PostExecute handle result from task...
                if(entity != null) {
                  val reader = new BufferedReader(new InputStreamReader(entity.getContent()))
                  val line = reader.readLine()
                  val (oauth_request_token, oauth_token_secret) = OAuthTokenExtractor(line)
    
                  // Store request tokens so they can be used when retrieving auth tokens...
                  val editor = getSharedPreferences(PreferenceFile(), 0).edit()
                  editor.putString("oauth_request_token", oauth_request_token)
                  editor.putString("oauth_token_secret", oauth_token_secret)
                  editor.commit()
    
                  // Start browser...
                  val intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl + oauth_request_token))
                  startActivity(intent)
                  val authButton = findViewById(R.id.authButton).asInstanceOf[Button]
                  authButton.setVisibility(View.VISIBLE)                
                }
              }).doInBackground()
            } catch {
              case e:Exception => Log.e("ERROR", "ERROR IN CODE:"+e.toString())
            }
          }
        })
      }
    
      private def retrieveAuthTokenAndSecret() = {
        val authVerifier = getAuthVerifier()  
        val accessPost = new HttpPost(accessUrl)
        val prefs = getSharedPreferences(PreferenceFile(), 0)
        val token = prefs.getString("oauth_request_token","")
        val secret = prefs.getString("oauth_token_secret","")
        accessPost.setHeader("Authorization", OAuthHeaderBuilder(token, secret, authVerifier))
        accessPost.setHeader("Content-Type", "application/x-www-form-urlencoded")
        val accessResp = client.execute(accessPost)
        val entity = accessResp.getEntity()
        if(entity != null) {
          val reader = new BufferedReader(new InputStreamReader(entity.getContent()))
          val builder = new StringBuilder()
          val line = reader.readLine()
          val (oauth_token, oauth_token_secret) = OAuthTokenExtractor(line)
          val result = new Intent()
          val editor = getSharedPreferences(PreferenceFile(), 0).edit()
          editor.putString("oauth_token", oauth_token)
          editor.putString("oauth_token_secret", oauth_token_secret)
          editor.commit()
    
          setResult(Activity.RESULT_OK, result)
          finish()
        }
      } 
    }
    

    OAuthHeaderBuilder 基本上是 Yammer oauth 示例代码的副本:

    object OAuthHeaderBuilder {
      // Apply function taken from the Yammer oauth sample 
      def apply(token:String, secret:String,verifier:String):String = {
        val buff = new StringBuilder()
        val currentTime = System.currentTimeMillis()
        // Hardcoded values for consumer key and secret...
        val consumerKey = "<your consumer key here>"
        val consumerSecret = "<your consumer secret here>"
        buff.append("OAuth realm=\"");
        buff.append("\", oauth_consumer_key=\"");
        buff.append(consumerKey);
        buff.append("\", ");
    
        if (token != null) {
          buff.append("oauth_token=\"");
          buff.append(token);
          buff.append("\", ");
        }
    
        buff.append("oauth_signature_method=\"");
        buff.append("PLAINTEXT");
        buff.append("\", oauth_signature=\"");
        buff.append(consumerSecret);
        buff.append("%26");
        if (secret != null) {
          buff.append(secret);
        }
        buff.append("\", oauth_timestamp=\"");
        buff.append(currentTime);
        buff.append("\", oauth_nonce=\"");
        buff.append(currentTime);
    
        if (verifier != null) {
          buff.append("\", ");
          buff.append("oauth_verifier=\"");
          buff.append(verifier);
        }
    
        buff.append("\", oauth_version=\"1.0\"");
    
        return buff.toString();
      }
    }
    

    为了提取令牌,我创建了一个 OAuthTokenExtractor 对象...

    object OAuthTokenExtractor {
      def apply(line:String) = {
        val token = (line split ("&")).find(x => x.startsWith("oauth_token=")) match {
          case Some(oauth_token) => (oauth_token split ("=") )(1)
          case _ => ""
        }   
        val secret = (line split ("&")).find(x => x.startsWith("oauth_token_secret=")) match {
          case Some(oauth_token_secret) => (oauth_token_secret split ("=") )(1)
          case _ => ""
        }   
        (token,secret)
      }
    }
    

    希望对你有帮助:)

    【讨论】:

      【解决方案4】:

      最好使用this article作为参考:

      在当前版本的 Signpost 中有一个获取认证 URL 的代码是:

      provider.retrieveRequestToken(CALLBACK_URL);
      

      (请务必使用CommonsHttpOAuthConsumerCommonsHttpOAuthProvider

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-22
        • 2012-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-05
        • 2017-10-26
        • 2017-01-10
        相关资源
        最近更新 更多