在C#中调用django rest framework需要身份认证的api

9 篇文章 0 订阅

最近在项目中需要将设备的数据上传到网站,决定使用webservice。在如何调用需要身份认证的api上犯了愁,搜了无数文章都说是用Credentials,但就是不行,返回403,后来还是铁了心看官方文档,发现了问题。


#setting.py
INSTALLED_APPS = (
    #......
    'rest_framework',
)

REST_FRAMEWORK = {
     # Use hyperlinked styles by default.
    # Only used if the `serializer_class` attribute is not set on a view.
    'DEFAULT_MODEL_SERIALIZER_CLASS':
        'rest_framework.serializers.HyperlinkedModelSerializer',

    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ],

    #这里是关键
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),

    'PAGINATE_BY': 10
}

#models.py
class DeviceValue(models.Model):
    """
    Value sampled from device
    """
    sample_time = models.DateTimeField(unique=True)
    value = models.FloatField()

from django.shortcuts import render
from django.http import HttpRequest, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import action
from rest_framework import viewsets
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import AllowAny, IsAuthenticatedOrReadOnly
from models import DeviceValue
import logging
from serializers import DeviceValueSerializer
# Create your views here.

class JSONResponse(HttpResponse):
    """
    An HttpResponse that renders its content into JSON.
    """
    def __init__(self, data, **kwargs):
        content = JSONRenderer().render(data)
        kwargs['content_type'] = 'application/json'
        super(JSONResponse, self).__init__(content, **kwargs)


class DeviceValueViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows device value to be viewed or edited.
    """
    queryset = DeviceValue.objects.all()
    serializer_class = DeviceValueSerializer
    #注意这里我将BasicAuthentication放在了SessionAuthentication前面,否则
    #会先用SessionAuthentication认证,而这会造成C#的NetworkCredentials认证失败
    authentication_classes = (BasicAuthentication, SessionAuthentication, )
    permission_classes = (IsAuthenticatedOrReadOnly,)

    @csrf_exempt
    @action(methods=['POST', ])
    def create_device_value(self, request):
        data = JSONParser().parse(request)
        serializer = DeviceValueSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JSONResponse(serializer.data, status=201, )
        return JSONResponse(serializer.errors, status=400, )

#serializers.py
from rest_framework import serializers
from models import DeviceValue


class DeviceValueSerializer(serializers.ModelSerializer):
    class Meta:
        model = DeviceValue
        fields = ('sample_time', 'value')

#urls.py
from django.conf.urls import patterns, include, url

from rest_framework import routers
from product_info import views
from django.contrib import admin
admin.autodiscover()


router = routers.DefaultRouter()
router.register(r'value', views.DeviceValueViewSet)

urlpatterns = patterns('product_info.views',
    # Examples:
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
)

C#中这样:

var request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.Credentials = new NetworkCredential(user, password);
            request.ContentType = @"application/json";
            var json = "{\"sample_time\": \"2013-05-25 14:21:38+03:00\", \"value\": 20}";            
            using (var stream = new StreamWriter(request.GetRequestStream()))
            {
                stream.Write(json);
                stream.Flush();
            }
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                Debug.WriteLine(response.StatusCode);
                using (var stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    var str = stream.ReadToEnd();
                    Debug.WriteLine(str);
                }                
            }
        }


重点都注释了,希望给其它人帮助。


PS: 一直都偷懒,有问题先Google,stackoverflow,找解决方案,以后这种态度要改,有时间的情况下还是要先浏览一下官方文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值