2010-12-16 7 views
8

He estado leyendo mucho en django-piston y usando para hacer una API para una aplicación que estoy desarrollando, pero estoy colgando en el lado del cliente del mundo. He escrito los manejadores y las asignaciones de uri, y puedo devolver JSON o XML al contenido de mi corazón. Donde me estoy estancando es qué hacer con eso ahora.¿Cuál es la forma correcta de escribir un cliente django-piston?

Mi objetivo final es que un cliente de iPhone y Android consuma y devuelva datos, pero no conozco la forma correcta de manejar la autenticación. La forma más fácil que puedo imaginarme es guardar el nombre de usuario y la contraseña en el dispositivo y etiquetar cada solicitud con él, en última instancia, usando la Autenticación básica, pero eso da como resultado un error. He consultado el soporte de piston para OAuth y he conseguido que funcione con la ayuda de this tutorial, pero tampoco parece la respuesta correcta. En última instancia, me gustaría tener un aviso simple en el dispositivo para el nombre de usuario y la contraseña, los cuales se enviarán a Django a través de Piston y REST, y se volverá a presionar una tecla de API. El dispositivo almacenará esa clave y etiquetará todas las solicitudes posteriores con ella. Eso se siente de la manera correcta, pero no puedo entender cómo hacerlo. ¿Puede alguien señalarme en la dirección correcta?

+0

¿Qué pasa con OAuth? – klemens

Respuesta

22

Puede escribir su propio módulo de autenticación. He aquí un ejemplo:

class ApiKeyAuthentication(object): 

    def is_authenticated(self, request): 
     auth_string = request.META.get("HTTP_AUTHORIZATION") 

     if not auth_string: 
      return False 

     key = get_object_or_None(ApiKey, key=auth_string) 

     if not key: 
      request.user = AnonymousUser() 
      return False 

     request.user = key.user 

     return True 

    def challenge(self): 
     resp = HttpResponse("Authorization Required") 
     resp['WWW-Authenticate'] = "Key Based Authentication" 
     resp.status_code = 401 
     return resp 

Tendrá un modelo para almacenar un mapeo de las claves de la API a los usuarios:

class ApiKey(models.Model): 
    user = models.ForeignKey(User, related_name='keys') 
    key = models.CharField(max_length=KEY_SIZE) 

Tendrá algún método para generar las claves reales. Algo como esto va a funcionar (por ejemplo, en save método del modelo ApiKey:

key = User.objects.make_random_password(length=KEY_SIZE) 

while ApiKey.objects.filter(key__exact=key).count(): 
    key = User.objects.make_random_password(length=KEY_SIZE) 

Por último, conectar su nuevo motor de autenticación:

# urls.py 

key_auth = ApiKeyAuthentication() 

def ProtectedResource(handler): 
    return resource.Resource(handler=handler, authentication=key_auth) 

your_handler = ProtectedResource(YourHandler) 

Como para el bombeo de nombre de usuario/contraseña de una clave de API, solo escriba un controlador que use BasicAuthentication para crear y devolver nueva ApiKey (para request.user).

+0

Brillante. Básicamente lo que estaba pensando que sería, por lo que le agradezco que lo deletree de manera concreta. Gracias ! – eddieroger

Cuestiones relacionadas