Skip to content

Commit ac7b37d

Browse files
authored
Merge pull request #2098 from plotly/flex-jwt-expiry
Allow both 400 and 401 for JWT expiry responses
2 parents c124fdf + 260f9ad commit ac7b37d

File tree

6 files changed

+18
-7
lines changed

6 files changed

+18
-7
lines changed

Diff for: CHANGELOG.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
66

77
### Fixed
88

9+
- [#2098](https://github.com/plotly/dash/pull/2098) Accept HTTP code 400 as well as 401 for JWT expiry
910
- [#2097](https://github.com/plotly/dash/pull/2097) Fix bug [#2095](https://github.com/plotly/dash/issues/2095) with TypeScript compiler and `React.FC` empty valueDeclaration error & support empty props components.
1011

1112
## [2.5.1] - 2022-06-13
@@ -35,8 +36,8 @@ This feature can be disabled by providing an empty viewport meta tag. e.g. `app
3536

3637
### Fixed
3738

38-
- [#2043](https://github.com/plotly/dash/pull/2043) Fix bug
39-
[#2003](https://github.com/plotly/dash/issues/2003) in which
39+
- [#2043](https://github.com/plotly/dash/pull/2043) Fix bug
40+
[#2003](https://github.com/plotly/dash/issues/2003) in which
4041
`dangerously_allow_html=True` + `mathjax=True` works in some cases, and in some cases not.
4142
- [#2065](https://github.com/plotly/dash/pull/2065) Fix bug [#2064](https://github.com/plotly/dash/issues/2064) rendering of `dcc.Dropdown` with a value but no options.
4243
- [#2047](https://github.com/plotly/dash/pull/2047) Fix bug [#1979](https://github.com/plotly/dash/issues/1979) in which `DASH_DEBUG` as environment variable gets ignored.

Diff for: dash/dash-renderer/src/actions/api.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ export default function apiThunk(endpoint, method, store, id, body) {
6565
return;
6666
}
6767

68-
if (res.status === STATUS.UNAUTHORIZED) {
68+
if (
69+
res.status === STATUS.UNAUTHORIZED ||
70+
res.status === STATUS.BAD_REQUEST
71+
) {
6972
if (hooks.request_refresh_jwt) {
7073
const body = await res.text();
7174
if (body.includes(JWT_EXPIRED_MESSAGE)) {

Diff for: dash/dash-renderer/src/actions/callbacks.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,8 @@ export function executeCallback(
536536
lastError = res;
537537
if (
538538
retry <= MAX_AUTH_RETRIES &&
539-
res.status === STATUS.UNAUTHORIZED
539+
(res.status === STATUS.UNAUTHORIZED ||
540+
res.status === STATUS.BAD_REQUEST)
540541
) {
541542
const body = await res.text();
542543

Diff for: dash/dash-renderer/src/constants/constants.js

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export const JWT_EXPIRED_MESSAGE = 'JWT Expired';
55
export const STATUS = {
66
OK: 200,
77
PREVENT_UPDATE: 204,
8+
// We accept both 400 and 401 for JWT token expiry responses.
9+
// Some servers use code 400 for expired tokens, because
10+
// they reserve 401 for cases that require user action
11+
BAD_REQUEST: 400,
812
UNAUTHORIZED: 401,
913
CLIENTSIDE_ERROR: 'CLIENTSIDE_ERROR',
1014
NO_RESPONSE: 'NO_RESPONSE'

Diff for: dash/development/base_component.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def _set_random_id(self):
196196
"""
197197
)
198198

199-
v = str(uuid.UUID(int=rd.randint(0, 2 ** 128)))
199+
v = str(uuid.UUID(int=rd.randint(0, 2**128)))
200200
setattr(self, "id", v)
201201
return v
202202

Diff for: tests/integration/renderer/test_request_hooks.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import functools
33
import flask
4+
import pytest
45

56
from dash import Dash, Output, Input, html, dcc
67
from werkzeug.exceptions import HTTPException
@@ -195,7 +196,8 @@ def update_output(value):
195196
assert dash_duo.get_logs() == []
196197

197198

198-
def test_rdrh003_refresh_jwt(dash_duo):
199+
@pytest.mark.parametrize("expiry_code", [401, 400])
200+
def test_rdrh003_refresh_jwt(expiry_code, dash_duo):
199201

200202
app = Dash(__name__)
201203

@@ -260,7 +262,7 @@ def wrap(*args, **kwargs):
260262
):
261263
# Read the data to prevent bug with base http server.
262264
flask.request.get_json(silent=True)
263-
flask.abort(401, description="JWT Expired " + str(token))
265+
flask.abort(expiry_code, description="JWT Expired " + str(token))
264266
except HTTPException as e:
265267
return e
266268
return func(*args, **kwargs)

0 commit comments

Comments
 (0)