我一直在学习本教程,因为我被告知Retrofit
是用于oAuth和网络调用的最佳API:
Retrofit oAuth2 tutorial
似乎运行良好,并且我已检索到授权代码,没有任何问题。但是,当使用他们提供的代码将其交换为访问令牌时,我似乎得到了nullpointer
并成为Retrofit
的初学者,我不确定自己做错了什么
ServiceGenerator类:
public class ServiceGenerator {
public static final String API_BASE_URL = "https://xxxx.xxxx.com/oauth/";
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null);
}
public static <S> S createService(
Class<S> serviceClass, String clientId, String clientSecret) {
if (!TextUtils.isEmpty(clientId)
&& !TextUtils.isEmpty(clientSecret)) {
String authToken = Credentials.basic(clientId, clientSecret);
return createService(serviceClass, authToken);
}
return createService(serviceClass, null, null);
}
public static <S> S createService(
Class<S> serviceClass, final String authToken) {
if (!TextUtils.isEmpty(authToken)) {
AuthenticationInterceptor interceptor =
new AuthenticationInterceptor(authToken);
if (!httpClient.interceptors().contains(interceptor)) {
httpClient.addInterceptor(interceptor);
builder.client(httpClient.build());
retrofit = builder.build();
}
}
return retrofit.create(serviceClass);
}
}
AuthenticationInterceptor类:
public class AuthenticationInterceptor implements Interceptor {
private String authToken;
public AuthenticationInterceptor(String token) {
this.authToken = token;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.header("Authorization", authToken);
Request request = builder.build();
return chain.proceed(request);
}
}
访问令牌类:
public class AccessToken {
private String accessToken;
private String tokenType;
public String getAccessToken() {
return accessToken;
}
public String getTokenType() {
// OAuth requires uppercase Authorization HTTP header value for token type
if (! Character.isUpperCase(tokenType.charAt(0))) {
tokenType =
Character
.toString(tokenType.charAt(0))
.toUpperCase() + tokenType.substring(1);
}
return tokenType;
}
}
最重要的是,我的oAuth类:
public class oAuthAuthentication extends Activity {
// you should either define client id and secret as constants or in string resources
private final String clientId = "xxxxxxxxxxxxxxx";
private final String clientSecret = "xxxxxxx";
private final String redirectUri = "https://xxxx.xxxx.xxx/rest/callback.html";
private String AUTH_URL;
private String AuthCode;
String grantType;
AccessToken accessToken;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.oauth);
Button loginButton = (Button) findViewById(R.id.login);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String url = AUTH_URL;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
});
}
@Override
protected void onResume() {
super.onResume();
// the intent filter defined in AndroidManifest will handle the return from ACTION_VIEW intent
Uri uri = getIntent().getData();
if (uri != null && uri.toString().startsWith(redirectUri)) {
new AsyncTaskRunner().execute();
} else {
Log.e("ERROR", "Error has occured with AuthCode");
}
}
public interface LoginService {
@FormUrlEncoded
@POST("/oauth/token")
Call<AccessToken> getAccessToken(
@Field("code") String code,
@Field("grant_type") String grantType,
@Field("client_id") String clientID,
@Field("client_secret") String clientSecret,
@Field("redirect_uri") String redirectUri);
}
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
Uri uri = getIntent().getData();
if (uri != null && uri.toString().startsWith(redirectUri)) {
// use the parameter your API exposes for the code (mostly it's "code")
String code = uri.getQueryParameter("code");
if (code != null) {
AuthCode = code;
LoginService loginService =
ServiceGenerator.createService(LoginService.class, clientId, clientSecret);
Call<AccessToken> call = loginService.getAccessToken(code, "authorization_code");
try {
accessToken = call.execute().body();
Log.e("token", accessToken.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return String.valueOf(accessToken);
}
}
}
我要访问的AccessToken端点是https://xxxx.xxxx.com/oauth/token
使用Retrofit for oAuth的人可以帮助我吗? P.s.我检查了我所有的值都是正确的,ID,机密,代码正在正常生成,并且Grant_type应该等于所述的“ authorization_code”。