How to implement a refresh token process with JWT for Android apps -
i'm working on oauth2 token system access rest api android app. i'm having problems token refreshment part on client side.
here flow : app makes request (with access token in parameter) server asynctask ( postcommentasynctask()
, addfriendasynctask()
etc...), if accesstoken valid it's ok, if has expired call asynctask
(getrefreshtokenasynctask()
) onpostexecute()
method of precedent asynctask
new accesstoken. here tricky part me. when new access token want re-execute initial asynctask request server. can't figure out how properly.
example1 :
request postcommentasynctask()
--> (acesstoken expired) -->getrefreshtokenasynctask()
-->request postcommentasynctask()
--> (good token)--> ok
edit:
i chose use volley
library ( no need use asynctask anymore ). use json web token
can check expire date wich encoded in payload of token.
here isaccesstokenexpired()
method check if access token not expired before making request server :
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; } }
and here refreshjsonwebtoken()
method new pair of access token/refresh token 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); }
and finnally getpost()
method use precedent methods :
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); }
i think handler
better in case because looper
has synchronous message queue convenient here. create handlerthread
, associate handler
it. can call postrunnable
on depending on needs, e.g. add postcommentrunnable
, if token has expired add getrefreshtokenrunnable
, postcommentrunnable
, - executed sequentially.
if still want go asynctasks
, can check whether token has expired before launching postcommentasynctask
? think better design. if can't, can execute them 1 after because work on same background thread default, e.g.:
new postcommentasynctask().execute(); class postcommentasynctask extends asynctask { //... onpostexecute() { if (tokenexpired) { new getrefreshtokenasynctask().execute(); new postcommentasynctask().execute(); // guy wait till refresh token executed. } } }
Comments
Post a Comment