Django subdomain configuration for API endpoints

前端 未结 2 709
你的背包
你的背包 2021-02-06 18:19

I\'ve set up a Django project which makes use of the django-rest-framework to provide some ReST functionality. The website and the rest functionality are all workin

2条回答
  •  日久生厌
    2021-02-06 19:06

    I had a similar issue with a Django based API. I found it useful to write a custom middleware class and use that to control which URLs were served on which subdomains.

    Django doesn't really care about subdomains when serving URLs, so assuming your DNS is set up such that api.example.com points to your Django project, then api.example.com/tasks/ will call the expected API view.

    The problem is that www.example.com/tasks/ would also call the API view, and api.example.com would serve the home page in a browser.

    So a bit of middleware can check that subdomains match up with URLs and raise 404 responses if appropriate:

    ## settings.py
    
    MIDDLEWARE_CLASSES += (
        'project.middleware.SubdomainMiddleware',
    )
    
    
    ## middleware.py
    
    api_urls = ['tasks']  # the URLs you want to serve on your api subdomain
    
    class SubdomainMiddleware:
        def process_request(self, request):
            """
            Checks subdomain against requested URL.
    
            Raises 404 or returns None
            """
            path = request.get_full_path()  # i.e. /tasks/
            root_url = path.split('/')[1]  # i.e. tasks
            domain_parts = request.get_host().split('.')
    
            if (len(domain_parts) > 2):
                subdomain = domain_parts[0]
                if (subdomain.lower() == 'www'):
                    subdomain = None
                domain = '.'.join(domain_parts[1:])
            else:
                subdomain = None
                domain = request.get_host()
    
            request.subdomain = subdomain  # i.e. 'api'
            request.domain = domain  # i.e. 'example.com'
    
            # Loosen restrictions when developing locally or running test suite
            if not request.domain in ['localhost:8000', 'testserver']:
                return  # allow request
    
            if request.subdomain == "api" and root_url not in api_urls:
                raise Http404()  # API subdomain, don't want to serve regular URLs
            elif not subdomain and root_url in api_urls:
                raise Http404()  # No subdomain or www, don't want to serve API URLs
            else:  
                raise Http404()  # Unexpected subdomain
            return  # allow request  
    

提交回复
热议问题