2012-09-24 13 views
5

Tengo un servidor que alimenta varias aplicaciones.Python: Cómo "bifurcar" una sesión en django

Imagina que soy un usuario registrado en 2 o más de esas aplicaciones y utilizo una información de inicio de sesión diferente al acceder a cada una de ellas.

Ahora, como ese usuario, utilizo el mismo navegador con diferentes pestañas para acceder a esas aplicaciones ... Registrando la primera vez (para la primera aplicación) todo va según lo previsto, pero cuando accedo a la segunda aplicación (como el segundo usuario), esa solicitud tendrá acceso al mismo objeto request.session. Cuando invoco el inicio de sesión (desde el marco de autenticación) el usuario actual se comparará con el usuario en el request.session (request.session[SESSION_KEY] != user.id) y se llamará al request.session.flush().

Esto significa que desatar todo el contenido request.session para el usuario que accede a la primera aplicación, y que un mismo usuario request.session será "marcado" para ser el segundo usuario request.session desde ese punto.

Lo que quería, en esta situación, era tener una función/método que permitiera crear un nuevo request.session para el segundo usuario, dejando el original tal como está.

Editado después de la primera respuesta: Antes que nada, gracias por la respuesta. Estaba tratando de no detallar demasiado para evitar respuestas demasiado orientadas, pero ahora creo que debería hacerlo:

Ok, he llamado aplicaciones "it" antes, pero en verdad, mi proyecto atiende solicitudes para ofrecer el mismo "producto" final (un juego, por ejemplo). (Tengo varias aplicaciones django dentro de mi proyecto. Cada una con orientaciones específicas y backend dependiendo de las consideraciones comerciales aplicadas)

Sería más detallado si dijera que tengo URL de puntos de entrada diferentes, uso el back-end de negocio correcto para procesar la solicitud y recuperar un juego.

Mi URL principal es la misma (espacio de nombres) y mi proyecto tiene solo un archivo de configuración.

enter image description here

+0

No estoy seguro de cómo Django puede insertar una cookie para el dominio para el que no se realizó la solicitud ** o ** www.2.com/playCDS --- redirect-to ---> www.me. com/playCDS luego cambia el perfil del usuario según el referente, ¿o sí? Todavía publiqué mi respuesta http://stackoverflow.com/a/12571909/140837, la actualizaré en consecuencia, pero la respuesta básica está allí, la lógica para el perfil de usuario de configuración cambia porque en su caso no parece haber un " cambiar la vista de subperfil ". – amirouche

+0

¿Hay algún modelo «SubProfile»? – amirouche

+0

¿revisó mi respuesta? – amirouche

Respuesta

2

Puede haber varias respuestas a su pregunta, dependiendo de si usted está listo para cambiar el "caso de uso" o no:

a) No se puede cambiar el caso de uso: no es posible debido a una La sesión de Django está vinculada a una sesión del navegador, ya sea en varias ventanas o pestañas de Windows.

b) Puede cambiar el caso de uso: El usuario aún puede lograrlo utilizando varios navegadores (o perfiles (o modo de navegación privada en cromo/cromo)) sin ninguna modificación a su código.

c) Puede implementar una característica -switch "usuario" en su sitio web que permitirá al usuario tener perfil activo varios en la misma sesión en diferentes ventanas, es una finalidad similar a github función de organización-interruptor o página de Facebook/organization-switch pero puede tener varios perfiles de usuario en varias pestañas, que no es el caso en github o facebook.

Para lograr c) es necesario tener un "SUB" instancias modelo que se adjunta a su modelo de "Usuario", y activar el subperfil derecha en cada petición entrante basada en los parámetros de cadena de consulta y mantener la información subperfil través de solicitudes.

1) supongo que ya tiene algo así Subprofile un modelo con una clave externa a django.contrib.auth.models.User, es posible que tenga una visión que permite a un usuario cambiar su subperfil. Para realizar un trabajo de conmutación de subperfil, debe persistir la información en la sesión de pestaña actual que subperfil está utilizando, para eso necesita agregar un parámetro en la cadena de consulta porque es el único lugar que limita la pestaña y no el usuario. -sesión. Por ejemplo, "subperfil = 123". . Es necesario validar adecuadamente el subperfil con una forma y otros, la vista se ve así:

def select_subprofile(request): 
    if request.method == 'POST': 
     form = SubProfileSelectForm(request) 
     if form.is_valid(): 
      subprofile = form.cleaned_data['subprofile'] 
      url = '%s?subprofile' % (reverse('homepage'), subprofile) 
      return redirect(url) # the redirect is something like '/homepage?subprofile=123' 
    else: 
     form = SubProfileSelectForm() 
    return render(request, 'myapp/subprofile_select.html', {'form':form}) 

Este punto de vista puede ser la primera página de cada juego.

2) Después de eso, debe recuperar el subperfil del usuario para la pestaña actual. Para este asunto utilizaremos la cadena de consulta en un middleware (busque howtos on SO y example middlewares bundled with Django si no sabe de qué se trata) se puede utilizar para adjuntar la instancia actual de SubProfile a . La voluntad de middleware para cada solicitud entrante adjuntar la instancia subperfil correspondiente a la información subperfil actual que se encuentra en la cadena de consulta al objeto de usuario actual, el middleware se ve así:

class SubProfileMiddleware(object): 

    def process_request(self, request): 
     subprofile = request.GET.get('subprofile', None) 
     if subprofile: 
      # it's important to check for user here or malicious users will be 
      # able to use Subprofiles of other users 
      subprofile = Subprofile.objects.filter(user=request.user, id=subprofile) 
      # This can also be written 
      # subprofile = request.user.subprofile_set.filter(id=subprofile) 
      if not subprofile: 
       # this is a malicious user 
       raise Http403 
      else: 
       request.user.subprofile = subprofile 
     else: 
      # set default subprofile 
      request.user.subprofile = self.user.default_subprofile 

De esta manera se tiene acceso en todas las vistas de su aplicación a una instancia SubProfile en el atributo subprofile de request.user. Si hay una cadena de consulta válida subprofile=123, el usuario tendrá este subperfil activo, si no es el subperfil predeterminado.

Supongamos que su aplicación es una aplicación con Organization modelos cada uno de los cuales tiene muros, en los que los usuarios pueden publicar mensajes utilizando un subperfil, la función para publicar un mensaje en una pared tiene la siguiente firma post_on_organization_wall(subprofile, message, organization), la vista que usa esto la función se verá así:

def organization_wall_post(request, organization): 
    organization = Organization.objects.get_object_or_404(organization) 
    if request.method == 'POST': 
     form = MessageForm(request.POST) 
     if form.is_valid(): 
      post_on_organization_wall(request.user.subprofile, message, organisation) 
    else: 
     form = MessageForm() 
    return render(request, 'organisation/wall_post.html', {'form': form}) 

3) Ahora tiene que mantener la información subperfil través de solicitudes. La forma más simple de hacerlo es reemplazar cada llamada a {% url %} a su propia etiqueta de plantilla url que comprueba la presencia de cadena de consulta de solicitud de la clave de subperfil y agregarla a la url solicitada. Puede reutilizar the code of Django's url template tag.

0

Si entiendo su problema correctamente, el problema es que va a compartir sesiones entre aplicaciones a pesar de que los usuarios son diferentes. Debería poder resolver esto estableciendo SESSION_COOKIE_DOMAIN, SESSION_COOKIE_PATH o SESSION_COOKIE_NAME en settings.py para asegurarse de que sus aplicaciones no superen las sesiones de los demás.

Cuestiones relacionadas