You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+6-1
Original file line number
Diff line number
Diff line change
@@ -21,11 +21,16 @@ Don't forget to remove deprecated code on each major release!
21
21
22
22
### Added
23
23
24
+
- User login/logout features!
25
+
-`reactpy_django.hooks.use_auth` to provide **persistent**`login` and `logout` functionality to your components.
26
+
-`settings.py:REACTPY_AUTH_TOKEN_TIMEOUT` to control the maximum seconds before ReactPy no longer allows the browser to obtain a persistent login cookie.
27
+
-`settings.py:REACTPY_CLEAN_AUTH_TOKENS` to control whether ReactPy should clean up expired authentication tokens during automatic cleanups.
24
28
- Automatically convert Django forms to ReactPy forms via the new `reactpy_django.components.django_form` component!
29
+
- The ReactPy component tree can now be forcibly re-rendered via the new `reactpy_django.hooks.use_rerender` hook.
25
30
26
31
### Changed
27
32
28
-
- Refactoring of internal code to improve maintainability. No changes to public/documented API.
33
+
- Refactoring of internal code to improve maintainability. No changes to publicly documented API.
Copy file name to clipboardExpand all lines: docs/src/reference/hooks.md
+82-5
Original file line number
Diff line number
Diff line change
@@ -271,6 +271,83 @@ Mutation functions can be sync or async.
271
271
272
272
---
273
273
274
+
## User Hooks
275
+
276
+
---
277
+
278
+
### Use Auth
279
+
280
+
Provides a `#!python NamedTuple` containing `#!python async login` and `#!python async logout` functions.
281
+
282
+
This hook utilizes the Django's authentication framework in a way that provides **persistent** authentication across WebSocket and HTTP connections.
283
+
284
+
=== "components.py"
285
+
286
+
```python
287
+
{% include "../../examples/python/use_auth.py" %}
288
+
```
289
+
290
+
??? example "See Interface"
291
+
292
+
<font size="4">**Parameters**</font>
293
+
294
+
`#!python None`
295
+
296
+
<font size="4">**Returns**</font>
297
+
298
+
| Type | Description |
299
+
| --- | --- |
300
+
| `#!python UseAuthTuple` | A named tuple containing `#!python login` and `#!python logout` async functions. |
301
+
302
+
??? warning "Extra Django configuration required"
303
+
304
+
Your ReactPy WebSocket must utilize `#!python AuthMiddlewareStack` in order to use this hook.
305
+
306
+
{% include "../../includes/auth-middleware-stack.md" %}
307
+
308
+
??? question "Why use this instead of `#!python channels.auth.login`?"
309
+
310
+
The `#!python channels.auth.*` functions cannot trigger re-renders of your ReactPy components. Additionally, it does not provide persistent authentication when used within ReactPy.
311
+
312
+
Django's authentication design requires cookies to retain login status. ReactPy is rendered via WebSockets, and browsers do not allow active WebSocket connections to modify cookies.
313
+
314
+
To work around this limitation, when `#!python use_auth().login()` is called within your application, ReactPy performs the following process...
315
+
316
+
1. The server authenticates the user into the WebSocket session
317
+
2. The server generates a temporary login token linked to the WebSocket session
318
+
3. The server commands the browser to fetch the login token via HTTP
319
+
4. The client performs the HTTP request
320
+
5. The server returns the HTTP response, which contains all necessary cookies
321
+
6. The client stores these cookies in the browser
322
+
323
+
This ultimately results in persistent authentication which will be retained even if the browser tab is refreshed.
324
+
325
+
---
326
+
327
+
### Use User
328
+
329
+
Shortcut that returns the WebSocket or HTTP connection's `#!python User`.
330
+
331
+
=== "components.py"
332
+
333
+
```python
334
+
{% include "../../examples/python/use_user.py" %}
335
+
```
336
+
337
+
??? example "See Interface"
338
+
339
+
<font size="4">**Parameters**</font>
340
+
341
+
`#!python None`
342
+
343
+
<font size="4">**Returns**</font>
344
+
345
+
| Type | Description |
346
+
| --- | --- |
347
+
| `#!python AbstractUser` | A Django `#!python User`, which can also be an `#!python AnonymousUser`. |
348
+
349
+
---
350
+
274
351
### Use User Data
275
352
276
353
Store or retrieve a `#!python dict` containing user data specific to the connection's `#!python User`.
@@ -522,7 +599,7 @@ You can expect this hook to provide strings such as `http://example.com`.
522
599
523
600
Shortcut that returns the root component's `#!python id` from the WebSocket or HTTP connection.
524
601
525
-
The root ID is a randomly generated `#!python uuid4`. It is notable to mention that it is persistent across the current connection. The `uuid` is reset when the page is refreshed.
602
+
The root ID is a randomly generated `#!python uuid4`. It is notable to mention that it is persistent across the current connection. The `uuid` is reset only when the page is refreshed.
526
603
527
604
This is useful when used in combination with [`#!python use_channel_layer`](#use-channel-layer) to send messages to a specific component instance, and/or retain a backlog of messages in case that component is disconnected via `#!python use_channel_layer( ... , group_discard=False)`.
528
605
@@ -546,14 +623,14 @@ This is useful when used in combination with [`#!python use_channel_layer`](#use
546
623
547
624
---
548
625
549
-
### Use User
626
+
### Use Re-render
550
627
551
-
Shortcut that returns the WebSocket or HTTP connection's `#!python User`.
628
+
Returns a function that can be used to trigger a re-render of the entire component tree.
552
629
553
630
=== "components.py"
554
631
555
632
```python
556
-
{% include "../../examples/python/use_user.py" %}
633
+
{% include "../../examples/python/use_rerender.py" %}
557
634
```
558
635
559
636
??? example "See Interface"
@@ -566,4 +643,4 @@ Shortcut that returns the WebSocket or HTTP connection's `#!python User`.
566
643
567
644
| Type | Description |
568
645
| --- | --- |
569
-
| `#!python AbstractUser` | A Django `#!python User`, which can also be an `#!python AnonymousUser`. |
646
+
| `#!python Callable[[], None]` | A function that triggers a re-render of the entire component tree. |
Dotted path to the Django authentication backend to use for ReactPy components. This is only needed if:
67
+
Dotted path to the Django authentication backend to use for ReactPy components. This is typically needed if:
70
68
71
69
1. You are using `#!python settings.py:REACTPY_AUTO_RELOGIN=True` and...
72
70
2. You are using `#!python AuthMiddlewareStack` and...
@@ -75,6 +73,22 @@ Dotted path to the Django authentication backend to use for ReactPy components.
75
73
76
74
---
77
75
76
+
### `#!python REACTPY_AUTH_TOKEN_TIMEOUT`
77
+
78
+
**Default:**`#!python 30`
79
+
80
+
**Example Value(s):**`#!python 5`
81
+
82
+
Maximum seconds before ReactPy no longer allows the browser to obtain a login cookie.
83
+
84
+
This setting exists because Django's authentication design require cookies to retain login status. ReactPy is rendered via WebSockets, and browsers do not allow active WebSocket connections to modify cookies.
85
+
86
+
To work around this limitation, this setting provides a maximum validity period of a temporary login token. When `#!python reactpy_django.hooks.use_auth().login()` is called within your application, ReactPy will automatically create this temporary login token and command the browser to fetch it via HTTP.
87
+
88
+
This setting should be a reasonably low value, but still be high enough to account for a combination of client lag, slow internet, and server response time.
89
+
90
+
---
91
+
78
92
### `#!python REACTPY_AUTO_RELOGIN`
79
93
80
94
**Default:**`#!python False`
@@ -141,9 +155,9 @@ This setting is incompatible with [`daphne`](https://github.com/django/daphne).
141
155
142
156
**Example Value(s):**`#!python True`
143
157
144
-
Configures whether to use an async ReactPy rendering queue. When enabled, large renders will no longer block smaller renders from taking place. Additionally, prevents the rendering queue from being blocked on waiting for async effects to startup/shutdown (which is typically a relatively slow operation).
158
+
Configures whether to use an async ReactPy rendering queue. When enabled, large renders will no longer block smaller renders from taking place. Additionally, prevents the rendering queue from being blocked on waiting for async effects to startup/shutdown (which is a relatively slow operation).
145
159
146
-
This setting is currently in early release, and currently no effort is made to de-duplicate renders. For example, if parent and child components are scheduled to render at the same time, both renders will take place even though a single render of the parent component would have been sufficient.
160
+
This setting is currently in early release, and currently no effort is made to de-duplicate renders. For example, if parent and child components are scheduled to render at the same time, both renders will take place, even though a single render would have been sufficient.
147
161
148
162
---
149
163
@@ -270,6 +284,16 @@ Configures whether ReactPy should clean up expired component sessions during aut
270
284
271
285
---
272
286
287
+
### `#!python REACTPY_CLEAN_AUTH_TOKENS`
288
+
289
+
**Default:**`#!python True`
290
+
291
+
**Example Value(s):**`#!python False`
292
+
293
+
Configures whether ReactPy should clean up expired authentication tokens during automatic clean up operations.
Copy file name to clipboardExpand all lines: docs/src/reference/template-tag.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -322,7 +322,7 @@ The entire file path provided is loaded directly into the browser, and must have
322
322
323
323
This template tag configures the current page to be able to run `pyscript`.
324
324
325
-
You can optionally use this tag to configure the current PyScript environment. For example, you can include a list of Python packages to automatically install within the PyScript environment.
325
+
You can optionally use this tag to configure the current PyScript environment, such as adding dependencies.
0 commit comments