Java 使用针对cloudinary的改进版2进行基本身份验证
我正试图使用下面的代码对Cloudinary API服务进行身份验证,但我收到了401个未经授权的错误,它需要此格式的凭据…,当我用实际值替换时,它在浏览器/邮递员中运行良好,但在改型2中失败,下面是我的代码Java 使用针对cloudinary的改进版2进行基本身份验证,java,android,retrofit2,cloudinary,Java,Android,Retrofit2,Cloudinary,我正试图使用下面的代码对Cloudinary API服务进行身份验证,但我收到了401个未经授权的错误,它需要此格式的凭据…,当我用实际值替换时,它在浏览器/邮递员中运行良好,但在改型2中失败,下面是我的代码 // create and initialize retrofit2 client public static OkHttpClient getClient(){ HttpLoggingInterceptor interceptor = new HttpLoggingIntercept
// create and initialize retrofit2 client
public static OkHttpClient getClient(){
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(Level.BASIC);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("API_KEY","API_SECRET")
.addHeader("Accept","Application/JSON").build();
return chain.proceed(request);
}
})
.addInterceptor(interceptor)
.build();
return client;
}
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl){
if (retrofit == null){
retrofit = new Retrofit.Builder()
.client(getClient())
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
// Interface with get methods to access image resources
public interface CloudinaryService {
@GET("resources/image")
Call<imageresponse> getImageResource();
}
// Util class to make requests
public class ApiUtils {
private static final String BASE_URL = "http://api.cloudinary.com/v...";
public static CloudinaryService getImageService(){
return RetrofitClient.getClient(BASE_URL)
.create(CloudinaryService.class);
}
}
我能够通过向生成器添加验证器来解决这个问题
.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
return response.request().newBuilder().header("Authorization", credentials).build();
}
})
谢谢你的帮助
request = chain.request();
builder = request.newBuilder();
if (TextUtils.isEmpty(request.header(AUTH)) && UserPreference.getInstance().isSignin())
builder.addHeader(AUTH, UserPreference.getInstance().getAccessToken());
if (NetUtil.hasNetwork(GridInnApplication.getInstance()))
builder.header(USER_AGENT, userAgent);
else
builder.cacheControl(CacheControl.FORCE_CACHE);
request = builder.build();
Response response = chain.proceed(request);
if (NetUtil.hasNetwork(GridInnApplication.getInstance())) {
String cacheControl = request.cacheControl().toString();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl)
.removeHeader(PRAGMA)
.build();
} else {
return response.newBuilder()
.addHeader(CACHE_CONTROL, CACHE_CONTROL_ONLY_CACHED)
.removeHeader(PRAGMA)
.build();
}
//您可以在重试截取之前返回结果leafNext提供的答案将起作用,但会导致每个请求发送两次-只有在服务器以401响应时,验证器才会生效。您发送请求,获取401,然后使用正确的凭据再次发送 正确的解决方案是使用拦截器从一开始就提供凭证。这与您最初尝试的操作类似,但语法错误。预期的格式是 其中,
凭证
应遵循基本身份验证协议:假设Api密钥为密钥
,且机密为机密
,则对表达式密钥:机密
进行base64编码,并在其前面加上基本
。在本例中,凭证
的值应以如下方式结束:
Basic a2V5OnNlY3JldA===
编辑-添加了一个完全工作的独立代码位,以验证基本身份验证是否适用于okhttp(因此在使用okhttp时进行了改装):
您没有在此处使用身份验证,这解释了错误。。。你希望如何通过认证?您是否尝试搜索“改装基本身份验证”?您没有将该数据作为标头传递。它需要此格式的凭据。。。,。你能解释一下吗,因为我看到你的
BASE\u URL
不一样。谢谢你的评论,我尝试了你上面的代码,但仍然返回401,但与authenticator一起工作,有什么线索吗?我读过其他博客,还记录了OKhttp调用我不确定你的两次身份验证理论是否正确,它似乎在第一次尝试时就截获了调用,并进行了良好的身份验证。请参阅。验证器是专门为中提到的重试而设计的。只有在收到401响应后,才会调用“还显示身份验证”
。不管怎样,你确认你的拦截器被激活了吗?你能发布更新的代码吗?是的,你是对的,但是当我通过截取器传递授权头时,我得到了401,我添加了最近的代码我编辑了我的答案,添加了一个肯定有效的代码位(用我的凭证测试)。使用您的云名称和凭据进行测试。如果这对ping me不起作用,我们将在chat中继续。
request = chain.request();
builder = request.newBuilder();
if (TextUtils.isEmpty(request.header(AUTH)) && UserPreference.getInstance().isSignin())
builder.addHeader(AUTH, UserPreference.getInstance().getAccessToken());
if (NetUtil.hasNetwork(GridInnApplication.getInstance()))
builder.header(USER_AGENT, userAgent);
else
builder.cacheControl(CacheControl.FORCE_CACHE);
request = builder.build();
Response response = chain.proceed(request);
if (NetUtil.hasNetwork(GridInnApplication.getInstance())) {
String cacheControl = request.cacheControl().toString();
return response.newBuilder()
.header(CACHE_CONTROL, cacheControl)
.removeHeader(PRAGMA)
.build();
} else {
return response.newBuilder()
.addHeader(CACHE_CONTROL, CACHE_CONTROL_ONLY_CACHED)
.removeHeader(PRAGMA)
.build();
}
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
// Request customization: add request headers
return chain.proceed(chain.request().newBuilder()
.header("Authorization", credentials).build());
}
});
public int testBasicAuth() throws IOException {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = (chain.request().newBuilder()
.header("Authorization",okhttp3.Credentials.basic(KEY, SECRET)).build());
return chain.proceed(request);
}
}).build();
Request request = new Request.Builder()
.url("https://api.cloudinary.com/v1_1/[cloud_name]/resources/image")
.build();
int code = client.newCall(request).execute().code();
return code; // 200
}