我正在创建使用REST Api的应用程序。我的API具有登录/注销功能,以便访问私人数据。我正在使用Retrofit + Robospice + Jackson创建消费者(客户端Android应用程序)
一切都很好,但是授权部分开始发挥作用了
我需要在请求Authorization Header
中提供令牌和其他凭据
使用RequestInterceptor
可以轻松完成此操作。这是完整的教程如何使用基本身份验证
Basic Authentication with Retrofit。
很清楚如何实现这一点。但在我的情况下,我也有可以在没有凭据的情况下访问的资源。
以下是使用Retrofit Annotations
声明的API的一部分public interface MalibuRestApi {
//Doesn't need credentials
@GET("/store/categories")
Category.List categoryList();
//Doesn't need credentials
@GET("/store/categories/{id}/products")
Product.List productList(@Path("id")int categoryId);
// Needs credentials
@POST("/store/users/{id}/logout")
// Needs credentials
User logout(@Path("id") int id,@Body Credentials userCredentials);
// Needs credentials !!!!!!!!!!!!!!!!!!!!
@POST("/store/users/{id}/orders/")
void makeAnOrder(@Path("id") int userId,@Body Order order,Callback<Void> callback);
}
请查看makeAnOrder
方法。它使用POST主体传递有关订单的详细信息。因此,结合凭证和订单似乎很糟糕而且效率不高,而且在任何情况下我都不会使用它。
可以使用拦截器。
builder.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
if
String token = .... // getting token.
request.addHeader("Accept", "application/json");
request.addHeader("Authorization",token);
}
});
我可以根据请求网址过滤请求并添加我需要的Auth标头,但是......
根据讨论here。
的 @JakeWharton
相对URL未在请求拦截器中公开,因为它 可能尚未完全解决。请求拦截器具有此功能 执行路径替换和追加查询参数
有一种可能的解决方法 @powerje
我不确定如何访问RequestInterceptor中的相对URL,但是 我在类似情况下使用的解决方案是检查我的UserManager (管理当前登录用户的全局)以查看用户 已登录,如果他们是我添加auth标头,否则我不会。
我已经在自定义应用程序类中创建了类似的类会话管理器,因此我假设它将一直存在,直到应用程序(linux dalvik / art process)被销毁。
所以有可能做这样的事情。
builder.setRequestInterceptor(new RequestInterceptor() {
@Override
public void intercept(RequestFacade request) {
sessionManager =(SessionProvider) getApplicationContext().getSessionManager();
if(sessionManager.userLoggedIn) {
String token = .... // getting token.
request.addHeader("Accept", "application/json");
request.addHeader("Authorization",token);
}
}
我还没有对此进行测试,但它假装工作 在这种情况下,冗余标头会传递给公共资源请求,而这些请求并不真正需要它们。
所以也许这可能是一种解决方案而不是一个问题,但我真的需要一些关于解决这个问题的任何其他方法(可能不是更好)的建议。
我将不胜感激任何帮助。