Java OAuth 1.0“;无法验证您的身份。”;

Java OAuth 1.0“;无法验证您的身份。”;,java,oauth,request,twitter-oauth,signature,Java,Oauth,Request,Twitter Oauth,Signature,首先,这是一个推特作者。我可以登录,我可以得到时间线等等。我可以得到这些东西,因为他们不需要额外的参数。但现在,我想添加“tweet_mode=extended”参数 public String extendedtweet(String token, String secret,String id) throws IOException{ String url="https://api.twitter.com/1.1/statuses/lookup.json"; header

首先,这是一个推特作者。我可以登录,我可以得到时间线等等。我可以得到这些东西,因为他们不需要额外的参数。但现在,我想添加“tweet_mode=extended”参数

 public String extendedtweet(String token, String secret,String id) throws IOException{

    String url="https://api.twitter.com/1.1/statuses/lookup.json";
    headercreator hc=new headercreator(outhconsumerkey,consumersecret,token,secret);
    Map<String,String> requestparams = new HashMap<String, String>();
    Log.e("id",id);
    requestparams.put("id",id);
    String header=hc.generateHeader("GET",url,requestparams);
    Log.e("header",header);

    Response response =request(url,"","GET","Authorization",header);
    String jsonData=response.body().string();
    JsonObject js=new Gson().fromJson(jsonData, JsonObject.class);
    return js.get("full_text").getAsString();


}
这行代码表示缺少id参数。这很好,因为这表明问题出在Headercreator类上,它在这里:

   package com.example.twittertestvol1;

import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * Class to generate Oauth 1.0a header for Twitter
 *
 */
@RequiresApi(api = Build.VERSION_CODES.N)
public class headercreator {

    private String consumerKey;
    private String consumerSecret;
    private String signatureMethod;
    private String token;
    private String tokenSecret;
    private String version;

    public headercreator(String consumerKey, String consumerSecret, String token, String tokenSecret) {
        this.consumerKey = consumerKey;
        this.consumerSecret = consumerSecret;
        this.token = token;
        this.tokenSecret = tokenSecret;
        this.signatureMethod = "HMAC-SHA1";
        this.version = "1.0";
    }

    private static final String oauth_consumer_key = "oauth_consumer_key";
    private static final String oauth_token = "oauth_token";
    private static final String oauth_signature_method = "oauth_signature_method";
    private static final String oauth_timestamp = "oauth_timestamp";
    private static final String oauth_nonce = "oauth_nonce";
    private static final String oauth_version = "oauth_version";
    private static final String oauth_signature = "oauth_signature";
    private static final String HMAC_SHA1 = "HmacSHA1";

    /**
     * Generates oAuth 1.0a header which can be pass as Authorization header
     *
     * @param httpMethod
     * @param url
     * @param requestParams
     * @return
     */
    public String generateHeader(String httpMethod, String url, Map<String, String> requestParams) {
        StringBuilder base = new StringBuilder();
        String nonce = getNonce();
        String timestamp = getTimestamp();
        String baseSignatureString = generateSignatureBaseString(httpMethod, url, requestParams, nonce, timestamp);
        String signature = encryptUsingHmacSHA1(baseSignatureString);
        base.append("OAuth ");
        append(base, oauth_consumer_key, consumerKey);
        append(base, oauth_token, token);
        append(base, oauth_signature_method, signatureMethod);
        append(base, oauth_timestamp, timestamp);
        append(base, oauth_nonce, nonce);
        append(base, oauth_version, version);
        append(base, oauth_signature, signature);
        base.deleteCharAt(base.length() - 1);
        return base.toString();
    }

    /**
     * Generate base string to generate the oauth_signature
     *
     * @param httpMethod
     * @param url
     * @param requestParams
     * @return
     */
    private String generateSignatureBaseString(String httpMethod, String url, Map<String, String> requestParams, String nonce, String timestamp) {
        Map<String, String> params = new HashMap<>();
        if (requestParams!=null)
        {
            requestParams.entrySet().forEach(entry -> {
                put(params, entry.getKey(), entry.getValue());
            });

        }
        put(params, oauth_consumer_key, consumerKey);
        put(params, oauth_nonce, nonce);
        put(params, oauth_signature_method, signatureMethod);
        put(params, oauth_timestamp, timestamp);
        put(params, oauth_token, token);
        put(params, oauth_version, version);
        Map<String, String> sortedParams = params.entrySet().stream().sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        StringBuilder base = new StringBuilder();
        sortedParams.entrySet().forEach(entry -> {
            base.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        });
        base.deleteCharAt(base.length() - 1);
        String baseString = httpMethod.toUpperCase() + "&" + encode(url) + "&" + encode(base.toString());
        return baseString;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private String encryptUsingHmacSHA1(String input) {
        String secret = new StringBuilder().append(encode(consumerSecret)).append("&").append(encode(tokenSecret)).toString();
        byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
        SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
        Mac mac;
        try {
            mac = Mac.getInstance(HMAC_SHA1);
            mac.init(key);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            return null;
        }
        byte[] signatureBytes = mac.doFinal(input.getBytes(StandardCharsets.UTF_8));
        return new String(Base64.getEncoder().encode(signatureBytes));
    }

    /**
     * Percentage encode String as per RFC 3986, Section 2.1
     *
     * @param value
     * @return
     */
    private String encode(String value) {
        String encoded = "";
        try {
            encoded = URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String sb = "";
        char focus;
        for (int i = 0; i < encoded.length(); i++) {
            focus = encoded.charAt(i);
            if (focus == '*') {
                sb += "%2A";
            } else if (focus == '+') {
                sb += "%20";
            } else if (focus == '%' && i + 1 < encoded.length() && encoded.charAt(i + 1) == '7' && encoded.charAt(i + 2) == 'E') {
                sb += '~';
                i += 2;
            } else {
                sb += focus;
            }
        }
        return sb.toString();
    }

    private void put(Map<String, String> map, String key, String value) {
        map.put(encode(key), encode(value));
    }

    private void append(StringBuilder builder, String key, String value) {
        builder.append(encode(key)).append("=\"").append(encode(value)).append("\",");
    }

    private String getNonce() {
        int leftLimit = 48; // numeral '0'
        int rightLimit = 122; // letter 'z'
        int targetStringLength = 10;
        Random random = new Random();

        String generatedString = random.ints(leftLimit, rightLimit + 1).filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)).limit(targetStringLength)
                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
        return generatedString;

    }

    private String getTimestamp() {
        return Math.round((new Date()).getTime() / 1000.0) + "";
    }

}

问题出现在
Response-Response=请求(url“,”获取“,”授权“,”标题)

调用服务时需要传入请求参数,但调用
request()
方法时没有传入
id
或任何其他参数。对我来说,以下代码有效:

public void getTweet(){
Map requestParams=new HashMap();
字符串id=“12632133480000325633”;
//传递头生成的所有请求参数
请求参数put(“id”,id);
请求参数put(“tweet_模式”、“扩展”);
字符串url=”https://api.twitter.com/1.1/statuses/lookup.json";
String header=generator.generateHeader(HttpMethod.GET.name(),url,requestParams);
HttpHeaders=新的HttpHeaders();
标题。添加(“授权”,标题);
HttpEntity HttpEntity=新的HttpEntity(“主体”,标题);
//传递请求中的所有请求参数
UriComponentsBuilder=UriComponentsBuilder.fromHttpUrl(url)
.queryParam(“id”,id)
.queryParam(“tweet_模式”、“扩展”);
ResponseEntity response=restemplate.exchange(builder.toUriString(),HttpMethod.GET,httpEntity,String.class);
字符串responseBody=response.getBody();
assertNotNull(responseBody);
系统输出打印LN(响应库);
}

junit可用的工作代码。

我正在编辑请求函数。您能检查一下如何在此处添加参数,如.Addheader(“id”,id)?ı现在无法测试钻机LOL
   package com.example.twittertestvol1;

import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * Class to generate Oauth 1.0a header for Twitter
 *
 */
@RequiresApi(api = Build.VERSION_CODES.N)
public class headercreator {

    private String consumerKey;
    private String consumerSecret;
    private String signatureMethod;
    private String token;
    private String tokenSecret;
    private String version;

    public headercreator(String consumerKey, String consumerSecret, String token, String tokenSecret) {
        this.consumerKey = consumerKey;
        this.consumerSecret = consumerSecret;
        this.token = token;
        this.tokenSecret = tokenSecret;
        this.signatureMethod = "HMAC-SHA1";
        this.version = "1.0";
    }

    private static final String oauth_consumer_key = "oauth_consumer_key";
    private static final String oauth_token = "oauth_token";
    private static final String oauth_signature_method = "oauth_signature_method";
    private static final String oauth_timestamp = "oauth_timestamp";
    private static final String oauth_nonce = "oauth_nonce";
    private static final String oauth_version = "oauth_version";
    private static final String oauth_signature = "oauth_signature";
    private static final String HMAC_SHA1 = "HmacSHA1";

    /**
     * Generates oAuth 1.0a header which can be pass as Authorization header
     *
     * @param httpMethod
     * @param url
     * @param requestParams
     * @return
     */
    public String generateHeader(String httpMethod, String url, Map<String, String> requestParams) {
        StringBuilder base = new StringBuilder();
        String nonce = getNonce();
        String timestamp = getTimestamp();
        String baseSignatureString = generateSignatureBaseString(httpMethod, url, requestParams, nonce, timestamp);
        String signature = encryptUsingHmacSHA1(baseSignatureString);
        base.append("OAuth ");
        append(base, oauth_consumer_key, consumerKey);
        append(base, oauth_token, token);
        append(base, oauth_signature_method, signatureMethod);
        append(base, oauth_timestamp, timestamp);
        append(base, oauth_nonce, nonce);
        append(base, oauth_version, version);
        append(base, oauth_signature, signature);
        base.deleteCharAt(base.length() - 1);
        return base.toString();
    }

    /**
     * Generate base string to generate the oauth_signature
     *
     * @param httpMethod
     * @param url
     * @param requestParams
     * @return
     */
    private String generateSignatureBaseString(String httpMethod, String url, Map<String, String> requestParams, String nonce, String timestamp) {
        Map<String, String> params = new HashMap<>();
        if (requestParams!=null)
        {
            requestParams.entrySet().forEach(entry -> {
                put(params, entry.getKey(), entry.getValue());
            });

        }
        put(params, oauth_consumer_key, consumerKey);
        put(params, oauth_nonce, nonce);
        put(params, oauth_signature_method, signatureMethod);
        put(params, oauth_timestamp, timestamp);
        put(params, oauth_token, token);
        put(params, oauth_version, version);
        Map<String, String> sortedParams = params.entrySet().stream().sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
        StringBuilder base = new StringBuilder();
        sortedParams.entrySet().forEach(entry -> {
            base.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        });
        base.deleteCharAt(base.length() - 1);
        String baseString = httpMethod.toUpperCase() + "&" + encode(url) + "&" + encode(base.toString());
        return baseString;
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private String encryptUsingHmacSHA1(String input) {
        String secret = new StringBuilder().append(encode(consumerSecret)).append("&").append(encode(tokenSecret)).toString();
        byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
        SecretKey key = new SecretKeySpec(keyBytes, HMAC_SHA1);
        Mac mac;
        try {
            mac = Mac.getInstance(HMAC_SHA1);
            mac.init(key);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            return null;
        }
        byte[] signatureBytes = mac.doFinal(input.getBytes(StandardCharsets.UTF_8));
        return new String(Base64.getEncoder().encode(signatureBytes));
    }

    /**
     * Percentage encode String as per RFC 3986, Section 2.1
     *
     * @param value
     * @return
     */
    private String encode(String value) {
        String encoded = "";
        try {
            encoded = URLEncoder.encode(value, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        String sb = "";
        char focus;
        for (int i = 0; i < encoded.length(); i++) {
            focus = encoded.charAt(i);
            if (focus == '*') {
                sb += "%2A";
            } else if (focus == '+') {
                sb += "%20";
            } else if (focus == '%' && i + 1 < encoded.length() && encoded.charAt(i + 1) == '7' && encoded.charAt(i + 2) == 'E') {
                sb += '~';
                i += 2;
            } else {
                sb += focus;
            }
        }
        return sb.toString();
    }

    private void put(Map<String, String> map, String key, String value) {
        map.put(encode(key), encode(value));
    }

    private void append(StringBuilder builder, String key, String value) {
        builder.append(encode(key)).append("=\"").append(encode(value)).append("\",");
    }

    private String getNonce() {
        int leftLimit = 48; // numeral '0'
        int rightLimit = 122; // letter 'z'
        int targetStringLength = 10;
        Random random = new Random();

        String generatedString = random.ints(leftLimit, rightLimit + 1).filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97)).limit(targetStringLength)
                .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
        return generatedString;

    }

    private String getTimestamp() {
        return Math.round((new Date()).getTime() / 1000.0) + "";
    }

}
private Response request(String url, String bodys, String type, String Headername, String Header) throws IOException {

    OkHttpClient client = new OkHttpClient();
    MediaType mediaType = MediaType.parse("text/plain");
    RequestBody body = RequestBody.create(mediaType,bodys);
    Request request;
    if (!Headername.equals(""))
    {
        if (type.equals("GET"))
        {

            request = new Request.Builder()
                    .url(url)
                    .method(type,null)
                    .addHeader(Headername,Header)
                    .build();

        }
        else{
            request = new Request.Builder()
                    .url(url)
                    .method(type, body)
                    .addHeader(Headername,Header)
                    .build();
        }

    }
    else {
        request = new Request.Builder()
                .url(url)
                .method(type, body)
                .build();

    }

    return client.newCall(request).execute();
}