Problem
I am currently struggling with a known issue related to submitting Django files that support authentication. The background of the problem is simple:
- We want to use Django Media File support.
- Media files are not private by default. In fact, usually the web server serves them directly.
- We want to authenticate users when accessing media files.
- We use token authentication in the interface
- Since there is no valid session, the browser cannot authenticate when accessing private files (for example, opening a PDF file in a new tab)
- We want Django to provide authentication for the browser, but must somehow authenticate using the existing authentication token
- We still want nginx to send the file back, so we will use
X-Accel-Redirect after authentication.
Attempts to solve
What I have done so far (and this works) creates another API view that requires token authentication and sends the file back, and then created an Angular directive to change all protected URLs to blob. When the user clicks on the link, he receives the file using token authentication, and then creates a blob that contains this data. Then the browser opens this blob.
Unfortunately, blobs cannot be exchanged, so users cannot embed links to each other for these files. I am wondering if there is a way around this.
purpose
My goal is to use a token to create a valid (and short expiration) session. Thus, when the user clicks on the link, a request is sent to check if there is a valid session, and then somehow configures the browser so that it can use this session. The whole process will look like this:
- Link to user clicks (which is actually a more complex Angular directive)
- Angular launches request for session to server
- The server responds with the necessary information.
- Using JavaScript to set up a browser session
- Make the browser open a connection to a newly created session.
- Confirm the user based on the session, use the header to transfer to the nginx file address
I am not looking for an implemented answer, I myself can process small details. I'm more interested in how this can be done in the best way. Namely:
- How do I customize the browser based on some session information in the API response?
- How should I handle the expiration of these sessions so that it is safe.
- How do I set up this session? Is it reasonable to check / create a session every time a link is clicked (suppose traffic is not a problem here)
- Is this a smart cross-browser solution? Is there a better way?
- How can I use an intermediate page to set up this session when the file URL is shared with a user who does not have a session but has a valid token?
Some options
Update: I spoke with some colleagues who contributed the following options:
- Instead of a session, ask the API to receive a one-time token or short-term token and add it to the file URL as a request parameter. Confirm this inside the request. This works, but still does not allow sharing URLs.
- Establish a session during login. If this session has expired when the user tries to access the file, redirect to the login to the session, and then during authentication redirect it back to the file. This also works, but I want to avoid the additional authentication step, as tokens have a long validity period and sessions have a short one. Providing them with the same validity period will also have disadvantages, as tokens that expire more often or sessions that expire less often are not ideal.
angularjs django django-rest-framework nginx session
Jamie counsell
source share