gpt4 book ai didi

android - 如何使用 JWT 为 Android 应用程序实现刷新 token 流程

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:13:22 25 4
gpt4 key购买 nike

我正在使用 Oauth2 token 系统来访问我的 Android 应用程序的 REST API。我在客户端的 token 刷新部分遇到了一些问题。

这是流程:我的应用程序向服务器发出请求(在参数中带有访问 token )感谢一些异步任务(PostCommentAsyncTask()AddFriendAsyncTask() 等...),所以如果 accessToken 有效就没问题,但如果它已过期,我会从 onPostExecute() 调用另一个 AsyncTask (GetRefreshTokenAsyncTask()) 方法的先例 AsyncTask 获取新的 accessToken。这对我来说是棘手的部分。当我获得新的访问 token 时,我想重新执行对服务器的初始 AsyncTask 请求。我不知道如何正确地做到这一点。

示例 1:

请求 PostCommentAsyncTask() --> (acessToken 过期) -->GetRefreshTokenAsyncTask()-->请求 PostCommentAsyncTask()--> (good token)--> 好的

编辑:

我最终选择了使用 Volley 库(不再需要使用 Asynctask 了)。当我使用 JSON Web Token 时,我可以检查在 token 的有效负载中编码的过期日期。

这是 isAccessTokenExpired() 方法,用于在向服务器发出请求之前检查访问 token 是否未过期:

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;
}

}

这是从我的 OAUTH2 服务器获取一对新的访问 token /刷新 token 的 refreshJsonWebToken() 方法:

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);


}

最后是 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);

}

最佳答案

我认为 Handler 在这种情况下更好,因为 Looper 具有同步消息队列,这在这里很方便。您创建一个 HandlerThread 并将您的 Handler 与其相关联。然后你可以根据需要调用 postRunnable ,例如您添加 PostCommentRunnable,如果 token 已过期,您添加 GetRefreshTokenRunnablePostCommentRunnable,它们将按顺序执行。

如果您仍然想使用 AsyncTasks,您可以在启动 PostCommentAsyncTask 之前检查 token 是否已过期吗?我认为那将是一个更好的设计。如果你不能,那么你可以一个接一个地执行它们,因为它们默认在同一个后台线程上工作,例如:

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.
}
}
}

关于android - 如何使用 JWT 为 Android 应用程序实现刷新 token 流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31596289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com