Fré*_*ric 5 android oauth-2.0 jwt android-asynctask android-volley
我正在使用Oauth2令牌系统来访问我的Android应用程序的REST API.我在客户端的令牌刷新部分遇到了一些问题.
这里是流:我的应用程序发出请求(在参数的访问令牌)的服务器由于一些的AsyncTask( PostCommentAsyncTask(),AddFriendAsyncTask()等...),所以如果是的accessToken有效这是确定的,但如果它已过期我调用另一个AsyncTask (GetRefreshTokenAsyncTask())从onPostExecute()先例的方法AsyncTask获得新的accessToken.这对我来说是棘手的部分.当我获得新的访问令牌时,我想重新执行对服务器的初始AsyncTask请求.我无法弄清楚如何正确地做到这一点.
example1:
请求PostCommentAsyncTask()- >(acessToken已过期) - > GetRefreshTokenAsyncTask()- >请求PostCommentAsyncTask()- >(好令牌) - >好的
编辑:
我最终选择使用该Volley库(不再需要使用Asynctask).在我使用时,JSON Web Token我可以检查在令牌的有效负载中编码的过期日期.
以下是在isAccessTokenExpired()向服务器发出请求之前检查访问令牌是否未过期的方法:
public Boolean isAccessTokenExpired(String accessToken){
String[] accessTokenPart = accessToken.split("\\.");
String header =accessTokenPart[0];
String payload =accessTokenPart[1];
String signature =accessTokenPart[2];
try {
byte[] decodedPayload = Base64.decode(payload, Base64.DEFAULT);
payload = new String(decodedPayload,"UTF-8");
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
JSONObject obj = new JSONObject(payload);
int expireDate = obj.getInt("exp");
Timestamp timestampExpireDate= new Timestamp( expireDate);
long time = System.currentTimeMillis();
Timestamp timestamp = new Timestamp(time);
return timestamp.after(timestampExpireDate);
} catch (JSONException e) {
e.printStackTrace();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是 refreshJsonWebToken()从我的OAUTH2服务器获取一对新的访问令牌/刷新令牌的方法:
public void refreshJsonWebToken(){
SharedPreferences settings = getActivity().getSharedPreferences(PREFS_NAME, 0);
String refreshToken = settings.getString("refreshToken", null);
final HashMap<String, String> params = new HashMap<String, String>();
params.put("grant_type","refresh_token");
params.put("client_id","client");
params.put("refresh_token",refreshToken);
JsonObjectRequest req = new JsonObjectRequest(URL_OAUTH2, new JSONObject(params), new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
String newRefreshToken = response.getString("refresh_token");
SharedPreferences settings = getActivity().getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("accessToken", newAccessToken);
editor.putString("refreshToken", newRefreshToken);
editor.apply();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("grid", "Error: " + error.getMessage());
}
}
});
AppController.getInstance().addToRequestQueue(req);
}
Run Code Online (Sandbox Code Playgroud)
最后getPost(),我使用先前方法的方法:
private void getPost(String latitude, String longitude) {
SharedPreferences settings = getActivity().getSharedPreferences(PREFS_NAME, 0);
String accessToken = settings.getString("accessToken", null);
final HashMap<String, String> params = new HashMap<String, String>();
params.put("action", "getLocalPosts");
params.put("latitude", latitude);
params.put("longitude", longitude);
if (isAccessTokenExpired(accessToken)){
refreshJsonWebToken();
}
settings = getActivity().getSharedPreferences(PREFS_NAME, 0);
accessToken = settings.getString("accessToken", null);
JsonObjectRequest req = new JsonObjectRequest(URL_APP+accessToken, new JSONObject(params), new Response.Listener<JSONObject>() {
//Some code ....
});
AppController.getInstance().addToRequestQueue(req);
}
Run Code Online (Sandbox Code Playgroud)
我认为Handler在这种情况下更好,因为Looper有同步消息队列,这在这里很方便。您创建一个HandlerThread并将您的Handler与它关联起来。然后您可以postRunnable根据您的需要调用它,例如您添加PostCommentRunnable, 如果令牌已过期您添加GetRefreshTokenRunnable和PostCommentRunnable, - 它们将按顺序执行。
如果您还想继续AsyncTasks,您可以在启动前检查一下令牌是否已过期吗PostCommentAsyncTask?我认为这将是一个更好的设计。如果不能,那么您可以依次执行它们,因为它们默认在同一个后台线程上工作,例如:
new PostCommentAsyncTask().execute();
class PostCommentAsyncTask extends AsyncTask {
//...
onPostExecute() {
if (tokenExpired) {
new GetRefreshTokenAsyncTask().execute();
new PostCommentAsyncTask().execute(); // this guy will wait till refresh token is executed.
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3064 次 |
| 最近记录: |