Where to Save a Jwt in a Browser-Based Application and How to Use It

Where to save a JWT in a browser-based application and how to use it

[EDIT] This answer is the accepted one, however the response from João Angelo is way more detailed and should be considered. One remark though and because the security pratices evolved since Nov. 2016, the Option 2 should be implemented in favour of the Option 1.

Look at this web site: https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/

If you want to store them, you should use the localStorage or sessionStorage if available or cookies.
You should also use the Authorization header, but instead of Basic scheme, use the Bearer one:

curl -v -X POST -H "Authorization: Bearer YOUR_JWT_HERE"

With JS, you could use the following code:

<script type='text/javascript'>
// define vars
var url = 'https://...';

// ajax call
$.ajax({
url: url,
dataType : 'jsonp',
beforeSend : function(xhr) {
// set header if JWT is set
if ($window.sessionStorage.token) {
xhr.setRequestHeader("Authorization", "Bearer " + $window.sessionStorage.token);
}

},
error : function() {
// error handler
},
success: function(data) {
// success handler
}
});
</script>

Where to store JWT in browser? How to protect against CSRF?

JWT tokens are popular since they are used as the default token format in new authorization and authentication protocols like OAuth 2.0 and OpenID Connect.

When the token is stored in a cookie, the browser will automatically send it along with each request to the same domain and this is still vulnerable to CSRF attacks.

Bearer authentication is one of the authentication schemes defined in HTTP. It basically means that YOU stick the (JWT) token in the Authorization HTTP header of a request. The browser will NOT do this for you automatically, so it's not suitable for protecting your website. As the browser does not automatically add the header to your request, it is not vulnerable to a CSRF attack, which depends on your authentication info being submitted automatically to the original domain.

The bearer scheme is often used to protect web APIs (REST services) that are consumed via AJAX calls or from mobile clients.

Where to store authorization (or JWT) tokens on the web browser based clients?

As security is your primary concern, then the answer is relatively simple: you can't supply a JWT as an authorization header to your server-side application. To do so would require the use of a Javascript-accessible object, meaning that the JWT is at risk of an XSS attack.

The only secure method available at present is to generate that token via your server application, then supply that token to your client-side SPA via a httpOnly, Secure cookie. Arguably, this cookie is now potentially vulnerable to CSRF, but this may be considered a lesser risk than XSS.

With each subsequent AJAX request, that cookie will then be automatically supplied by the browser. Your server application (or application server) must also be configured to accept the JWT via that specific cookie.

This technique works for any application - Single Page Application or otherwise - that is looking to protect requests to server-side resources.

Where should I save client's JWT for future requests?

You are right. It's not safe to store it in local storage.

The JWT needs to be stored inside an HttpOnly cookie, a special kind of cookie that's only sent in HTTP requests to the server, and it's never accessible (both for reading or writing) from JavaScript running in the browser.

You can read more about this on this article about JWT best practices. https://logrocket.com/blog/jwt-authentication-best-practices/

Where to store a JWT token?

If you are using REST service and want to store JWT the best way available is SharedPreferences.You should store in PrivateMode for security.

SharedPreference and SharedPreference.Editor is used to store and retrieve JWT. JWT is retrieved after POST request of Username and Password

 private void makeJsonRequest() {    
String json_req = "json_req";
// String url = getContext().getString(R.string.LOGIN_URL);
String url="";
final JSONObject obj=new JSONObject();
try{
obj.put("username",name);
obj.put("password",pass);

}catch (JSONException e)
{
e.printStackTrace();
}

JsonObjectRequest req = new JsonObjectRequest(Request.Method.POST, url, obj,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}

}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
return headers;
}
};
AppController.getInstance().addToRequestQueue(req, json_req);

To retrieve JWT from response and save in shared preference use

SharedPreferences prefs;
SharedPreferences.Editor edit;
prefs=getActivity().getSharedPreferences("myPrefs",Context.MODE_PRIVATE);
edit=prefs.edit();
try {
String saveToken=response.getString("token");
edit.putString("token",saveToken);
Log.i("Login",saveToken);
edit.commit();
}
catch (JSONException e)
{
e.printStackTrace();
}

To get Token from SharedPreference

private void getToken() {
prefs=this.getActivity().getSharedPreferences("myPrefs",Context.MODE_PRIVATE);
String token = prefs.getString("token","");
}


Related Topics



Leave a reply



Submit