Ich arbeite an einem Oauth2-Tokensystem, um auf meine REST-API für meine Android-App zuzugreifen. Ich habe einige Probleme mit der Token-Erfrischung auf der Client-Seite. HierSo implementieren Sie einen Aktualisierungstokenprozess mit JWT für Android-Apps
ist der Fluss: Meine app eine Anfrage (mit einem Zugriffstoken in Parameter) auf den Server durch einige AsyncTask (PostCommentAsyncTask()
, AddFriendAsyncTask()
etc ...), also wenn die accessToken gültig ist, es ist in Ordnung, aber wenn es abgelaufen ist, rufe ich einen anderen AsyncTask
(GetRefreshTokenAsyncTask()
) von der onPostExecute()
Methode des Präzedenzfalls AsyncTask
, um neue accessToken zu erhalten. Hier ist der schwierige Teil für mich. Wenn ich das neue Zugriffs-Token bekomme, möchte ich die ursprüngliche AsyncTask-Anfrage an den Server erneut ausführen. Ich kann nicht herausfinden, wie es richtig gemacht wird.
example1:
Anfrage PostCommentAsyncTask()
-> (acessToken abgelaufen) ->GetRefreshTokenAsyncTask()
-> Anfrage PostCommentAsyncTask()
-> (gut Token) -> Ok
EDIT:
Ich entschied mich schließlich für die Verwendung der Volley
Bibliothek (keine Notwendigkeit, Asynctask mehr zu verwenden). Da ich JSON Web Token
verwende, kann ich das Ablaufdatum überprüfen, das in der Nutzlast des Tokens kodiert ist. Hier
ist die isAccessTokenExpired()
Methode zu überprüfen, ob das Zugriffstoken nicht, bevor sie eine Anfrage an den Server abgelaufen ist:
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;
}
}
Und hier ist die refreshJsonWebToken()
Methode ein neues Paar von Access Token/Refresh-Token zu erhalten von meinem OAuth2 Server:
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);
}
Und finnally der getPost()
Methode, wo ich die Präzedenzfall Methoden verwenden:
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);
}
Sie konnten die 'bekommen verwenden()' Methode Ihrer zweiten 'AsyncTask' in 'doInBackground()' Methode der ersten 'AsyncTask'. Die Methode 'get()' von 'AsyncTask' ist eine Blocking-Methode, die ein Ergebnis zurückgibt - es ist völlig nutzlos, sie im main-/UI-Thread zu verwenden, aber wenn Sie sie vom ersten 'AsyncTask'-Befehl' doInBackground() 'aufrufen Methode (die auf einem eigenen Thread läuft), dann können Sie einfach mit der ursprünglichen Aufgabe fortfahren, sobald die zweite "AsyncTask" 'get()' Methode zurückkehrt. Nur eine Idee. – Squonk
@ Frédéric: Welche Bibliothek haben Sie auf der Serverseite für die OAuth2 Passwortvergabe verwendet? Ich benutze Knoten als Backend. – j10