Reputation: 1932
I have a Django web app that is using the Django REST framework to generate various API endpoints. I can ensure only logged in users can view/read these endpoints, but now I am at the stage of development where I want users to post to the API using tokens. I have successfully done this, however, I have hard-coded the users token into the post request in Javascript... This worked for testing but obviously is not a good final solution.
Is it possible to request the current users token somehow? Could I then include this token in the POST request head automatically?
Thanks for any help/feedback in advance!!
EDIT: I think I am close, but I am getting a few errors in my chrome console, and still can't retrieve token.
Console Errors:
toggleScript.js:25 Uncaught DOMException: Failed to execute
'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
at getToken (http://127.0.0.1:8000/static/defaults/toggleScript.js:25:7)
at manageDefaults
(http://127.0.0.1:8000/static/defaults/toggleScript.js:62:5)
at HTMLInputElement.onclick (http://127.0.0.1:8000/defaults/:1:1)
getToken @ toggleScript.js:25
manageDefaults @ toggleScript.js:62
onclick @ (index):1
toggleScript.js:24 POST http://127.0.0.1:8000/api-token-auth/ 415
(Unsupported Media Type)
I have a button when pressed, will trigger the function to retrieve the token, and this is what is causing the error stack above.
toggleScript.js
function getToken(){
var xhr = new XMLHttpRequest();
var url = 'http://127.0.0.1:8000/api-token-auth/';
xhr.open("POST", url, true);
var data = JSON.stringify({"username": "myusername", "password": "mypassword"});
xhr.send(data);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
console.log(json.token);
}
};
}
Upvotes: 0
Views: 610
Reputation: 23014
Django Rest Framework provides an API endpoint for requesting a user's token, given a username and password. You can wire the view into your urls.py
:
from rest_framework.authtoken import views
urlpatterns += [
url(r'^auth-token/', views.obtain_auth_token)
]
Then when you POST a valid username and password to that view it will return the token in a JSON response:
{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
Your app can then store that and send it in subsequent requests.
An example of retrieving the token using JQuery (assuming the view was mapped to the path ^auth-token/
in your urls.py
):
$.post('/auth-token/', { username: 'admin', password: 'whatever' }, function(data) {
// Token available as data.token
});
If you try and post to the auth-token
view from within an already authenticated session, Django will likely reject the request with a CSRF token missing or incorrect
response. You should either ensure that the session is not authenticated when you retrieve the token, or you could potentially include the X-CSRFToken
header in the request. You'd need to extract the value from the csrftoken
cookie. For example (using JQuery and the JQuery Cookie plugin):
$.ajax({
url: "/auth-token/",
type: "POST",
headers: {
"X-CSRFToken": $.cookie("csrftoken") # Extract the csrftoken from the cookie
},
data:{ username: "admin", password: "whatever" },
dataType:"json"
}).done(function(data) {
// Token available as data.token
});
More info on obtaining an auth token here
Upvotes: 1