Django Rest Framework - Integrate your backend¶
Minimal example¶
The following example creates a view which can only be accessed from logged-in users. It's derived from Django Rest Framework's tutorial, which is where the Snippet models and Serializers come from.
from propelauth_django_rest_framework import init_auth
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import permissions
auth = init_auth("YOUR_AUTH_URL", #(1)
"YOUR_API_KEY") #(2)
class SnippetViewSet(viewsets.ModelViewSet):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = [auth.IsUserAuthenticated] #(3)
def perform_create(self, serializer):
serializer.save(owner=self.request.propelauth_user.user_id) #(4)
- The base URL where your authentication pages are hosted. You can find this under the Backend Integration section for your project at https://app.propelauth.com.
- You can manage your api keys under the Backend Integration section for your project.
- This permission verifies the user is logged in and has passed in a valid access token.
- The permission also sets
request.propelauth_user
which has a user_id
How it works¶
You've seen that the frontend gets an access token.
When it makes an HTTP request, it provides this access token in an Authorization
header.
PropelAuth provides you with metadata that you use to validate the access token and figure out who it belongs to. The complexity of fetching the metadata and validating the tokens is hidden in the Django Rest Framework library.
Install¶
In your app, install the propelauth-django-rest-framework library.
Initialize¶
init_auth performs a one-time initialization of the library. It will verify your api_key
is correct and fetch the
metadata needed to verify access tokens in
IsUserAuthenticated, AllowAny, and IsUserInOrg.
from propelauth_django_rest_framework import init_auth
auth = init_auth("YOUR_AUTH_URL", #(1)
"YOUR_API_KEY") #(2)
- The base URL where your authentication pages are hosted. You can find this under the Backend Integration section for your project at https://app.propelauth.com.
- You can manage your api keys under the Backend Integration section for your project.
Protect API routes¶
IsUserAuthenticated¶
A permission that will verify the request was made by a valid user. Specifically, it will:
- Check that a valid access token was provided. If not, the request is rejected with a 401 status code.
- Set request.propelauth_user with the user's information.
from propelauth_django_rest_framework import init_auth, current_user
auth = init_auth("YOUR_AUTH_URL", "YOUR_API_KEY")
@api_view(['GET'])
@permission_classes([auth.IsUserAuthenticated])
def whoami(request):
return HttpResponse(request.propelauth_user.user_id)
or you can use it in class-based views:
class WhoAmIView(APIView):
permission_classes = [auth.IsUserAuthenticated]
def get(self, request):
return HttpResponse(request.propelauth_user.user_id)
AllowAny¶
Similar to IsUserAuthenticated, except if an access token is missing or invalid, the request is allowed to
continue, but request.propelauth_user
will be None
.
Note that this will still set request.propelauth_user
if a valid access token is provided.
class OptionalUserView(APIView):
permission_classes = [auth.AllowAny]
def get(self, request):
if request.propelauth_user is None:
return HttpResponse("none")
return HttpResponse(request.propelauth_user.user_id)
request.propelauth_user¶
A per-request value that contains user information for the user making the request. It's set by one of IsUserAuthenticated, AllowAny, or IsUserInOrg.
Property | Description |
---|---|
user_id | The id of the user |
org_id_to_org_member_info | A dictionary of org ids to metadata about the org. Includes all orgs that the user is in |
The values of org_id_to_org_member_info have these properties:
org_id_to_org_member_info properties | Description |
---|---|
org_id | The id of the org |
org_name | The name of the org |
user_role | The user's role within the org. See UserRole for more details. |
IsUserInOrg¶
A function that returns a permission that will verify the request was made by a valid user that belongs to a specific organization.
IsUserInOrg Argument | Description |
---|---|
req_to_org_id | A function that takes in the request and outputs the org_id to require the user to be a member of. If none is specified, it will check for a path param org_id by checking request.GET.get('org_id', '') . |
minimum_required_role | If specified, IsUserInOrg will check both that the user is a member of the organization, and that their role is >= minimum_required_role . If not, the request is rejected with a 403 Forbidden error. |
@api_view(['GET'])
@permission_classes([auth.IsUserInOrg(minimum_required_role=UserRole.Admin)])
def admins_only(request):
message = f"You are an admin or owner of {request.propelauth_org.org_name}"
return HttpResponse(message)
Specifically, it will:
- Check that a valid access token was provided. If not, the request is rejected with a 401 status code.
- Set request.propelauth_user with the user's information.
- Find an id for an organization within the request. By default, it will check for a path parameter org_id.
- Check that the user is a member of that organization. If not, the request is rejected with a 403 status code.
- (Optionally) Check that the user's role in that organization is
>= minimum_required_role
. If not, the request is rejected with a 403 status code. - Set request.propelauth_org (scoped to the current request) with the organization's information for this user.
request.propelauth_org¶
A per-request value that contains org information for the user making the request. It's set by IsUserInOrg.
Property | Description |
---|---|
org_id | The id of the org |
org_name | The name of the org |
user_role | The user's role within the org. See UserRole for more details. |
API calls¶
In addition to protecting API routes, you can make requests to PropelAuth to fetch more information about your users or organizations. You can also create new users, update user metadata, etc.
See the reference for everything you can do.
Next Steps¶
Done with your backend? Next you can deploy to production.