aboutsummaryrefslogtreecommitdiffstats
path: root/docs/tutorial/4-authentication-and-permissions.md
diff options
context:
space:
mode:
authorTom Christie2013-03-18 21:03:05 +0000
committerTom Christie2013-03-18 21:03:05 +0000
commit74fb366c595db87bb71baeffcacfb7d2482e3a18 (patch)
tree2e28cb52542742f32cdd3fbeb625f7f59cba0a3f /docs/tutorial/4-authentication-and-permissions.md
parent4c6396108704d38f534a16577de59178b1d0df3b (diff)
parent034c4ce4081dd6d15ea47fb8318754321a3faf0c (diff)
downloaddjango-rest-framework-74fb366c595db87bb71baeffcacfb7d2482e3a18.tar.bz2
Merge branch 'master' into resources-routers
Diffstat (limited to 'docs/tutorial/4-authentication-and-permissions.md')
-rw-r--r--docs/tutorial/4-authentication-and-permissions.md48
1 files changed, 32 insertions, 16 deletions
diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md
index f6daebb7..3ee755a2 100644
--- a/docs/tutorial/4-authentication-and-permissions.md
+++ b/docs/tutorial/4-authentication-and-permissions.md
@@ -22,7 +22,7 @@ We'd also need to make sure that when the model is saved, that we populate the h
We'll need some extra imports:
from pygments.lexers import get_lexer_by_name
- from pygments.formatters import HtmlFormatter
+ from pygments.formatters.html import HtmlFormatter
from pygments import highlight
And now we can add a `.save()` method to our model class:
@@ -54,8 +54,10 @@ You might also want to create a few different users, to use for testing the API.
Now that we've got some users to work with, we'd better add representations of those users to our API. Creating a new serializer is easy:
+ from django.contrib.auth.models import User
+
class UserSerializer(serializers.ModelSerializer):
- snippets = serializers.ManyPrimaryKeyRelatedField()
+ snippets = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = User
@@ -70,14 +72,14 @@ We'll also add a couple of views. We'd like to just use read-only views for the
serializer_class = UserSerializer
- class UserInstance(generics.RetrieveAPIView):
+ class UserDetail(generics.RetrieveAPIView):
model = User
serializer_class = UserSerializer
Finally we need to add those views into the API, by referencing them from the URL conf.
url(r'^users/$', views.UserList.as_view()),
- url(r'^users/(?P<pk>[0-9]+)/$', views.UserInstance.as_view()),
+ url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
## Associating Snippets with Users
@@ -102,8 +104,6 @@ This field is doing something quite interesting. The `source` argument controls
The field we've added is the untyped `Field` class, in contrast to the other typed fields, such as `CharField`, `BooleanField` etc... The untyped `Field` is always read-only, and will be used for serialized representations, but will not be used for updating model instances when they are deserialized.
-**TODO: Explain the SessionAuthentication and BasicAuthentication classes, and demonstrate using HTTP basic authentication with curl requests**
-
## Adding required permissions to views
Now that code snippets are associated with users, we want to make sure that only authenticated users are able to create, update and delete code snippets.
@@ -118,8 +118,6 @@ Then, add the following property to **both** the `SnippetList` and `SnippetDetai
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
-**TODO: Now that the permissions are restricted, demonstrate using HTTP basic authentication with curl requests**
-
## Adding login to the Browseable API
If you open a browser and navigate to the browseable API at the moment, you'll find that you're no longer able to create new code snippets. In order to do so we'd need to be able to login as a user.
@@ -159,12 +157,9 @@ In the snippets app, create a new file, `permissions.py`
Custom permission to only allow owners of an object to edit it.
"""
- def has_permission(self, request, view, obj=None):
- # Skip the check unless this is an object-level test
- if obj is None:
- return True
-
- # Read permissions are allowed to any request
+ def has_object_permission(self, request, view, obj):
+ # Read permissions are allowed to any request,
+ # so we'll always allow GET, HEAD or OPTIONS requests.
if request.method in permissions.SAFE_METHODS:
return True
@@ -182,10 +177,31 @@ Make sure to also import the `IsOwnerOrReadOnly` class.
Now, if you open a browser again, you find that the 'DELETE' and 'PUT' actions only appear on a snippet instance endpoint if you're logged in as the same user that created the code snippet.
+## Authenticating with the API
+
+Because we now have a set of permissions on the API, we need to authenticate our requests to it if we want to edit any snippets. We havn't set up any [authentication classes][authentication], so the defaults are currently applied, which are `SessionAuthentication` and `BasicAuthentication`.
+
+When we interact with the API through the web browser, we can login, and the browser session will then provide the required authentication for the requests.
+
+If we're interacting with the API programmatically we need to explicitly provide the authentication credentials on each request.
+
+If we try to create a snippet without authenticating, we'll get an error:
+
+ curl -i -X POST http://127.0.0.1:8000/snippets/ -d "code=print 123"
+
+ {"detail": "Authentication credentials were not provided."}
+
+We can make a successful request by including the username and password of one of the users we created earlier.
+
+ curl -X POST http://127.0.0.1:8000/snippets/ -d "code=print 789" -u tom:password
+
+ {"id": 5, "owner": "tom", "title": "foo", "code": "print 789", "linenos": false, "language": "python", "style": "friendly"}
+
## Summary
We've now got a fairly fine-grained set of permissions on our Web API, and end points for users of the system and for the code snippets that they have created.
-In [part 5][tut-5] of the tutorial we'll look at how we can tie everything together by creating an HTML endpoint for our hightlighted snippets, and improve the cohesion of our API by using hyperlinking for the relationships within the system.
+In [part 5][tut-5] of the tutorial we'll look at how we can tie everything together by creating an HTML endpoint for our highlighted snippets, and improve the cohesion of our API by using hyperlinking for the relationships within the system.
-[tut-5]: 5-relationships-and-hyperlinked-apis.md \ No newline at end of file
+[authentication]: ../api-guide/authentication.md
+[tut-5]: 5-relationships-and-hyperlinked-apis.md