establecer sesión: variable personalizada para almacenar la identificación del usuario

10

Quiero almacenar la identificación del usuario en una variable de sesión personalizada y usarla (leer) en los procedimientos de activación para autorizar las acciones del usuario. Encontré algo como esto:

set session "myapp.user" = '12345';
...
SELECT current_setting('myapp.user');

y parece funcionar: pensé que "myapp.user" debería declararse en el archivo .conf pero parece que puedo crear variables de sesión sobre la marcha (no cambié el archivo .conf en absoluto).

¿Hay alguna desventaja de hacer así?

usuario606521
fuente
2
Creo que la restricción que myapp.userdebe declararse postgresql.confse eliminó en 9.2 o 9.1
a_horse_with_no_name
55
Es una forma razonable de hacer las cosas siempre y cuando el usuario no tenga permitido ejecutar SQL arbitrario (en cuyo caso, simplemente podría establecer una ID de usuario diferente). Es una solución un poco hacky para la falta de variables de sesión verdaderas de PostgreSQL, pero no conozco ningún problema significativo con ella. Por cierto, por favor enlace a las preguntas / respuestas anteriores relevantes que utilizó como referencia .
Craig Ringer

Respuestas:

8

Antes de la versión 9.2, necesitaba agregar su variable de clase personalizada al custom_variable_classesparámetropostgresql.conf , como:

custom_variable_classes = 'myapp'

En 9.2, este requisito se ha eliminado :

Elimine el parámetro custom_variable_classes (Tom Lane)

La comprobación proporcionada por esta configuración era dudosa. Ahora cualquier configuración puede tener como prefijo cualquier nombre de clase.

Entonces, desde 9.2 solo puede configurar su variable de clase personalizada como lo está haciendo actualmente, no necesita preocuparse por cambiar postgresql.conf.

MatheusOl
fuente
0

Para casos como este, me gusta crear una función plperl como esta:

CREATE OR REPLACE FUNCTION session_store(key text,val text DEFAULT NULL)
  RETURNS text AS
$BODY$
my ($k,$v)=@_;
die "key cannot be NULL\n" unless defined $k;
if (defined $v) {
    $_SHARED{session_store}{$k}=$v;
    return undef;
}
return exists $_SHARED{session_store}{$k}?$_SHARED{session_store}{$k}:undef;
$BODY$
LANGUAGE plperl VOLATILE;

La ventaja de esto es que también funciona en sentencias sql, por ejemplo:

select session_store('user',12345::text);
insert into mytable(userid) values(session_store('user')::integer);
soger
fuente