A classe lrSession
Por definição, um servidor REST é do tipo "Stateless" (sem estado), o que significa que o solicitante deve poder chamar um método sem nenhum contexto prévio (o servidor não mantém entre duas chamadas nenhuma informação persistente referente ao cliente REST).
Não obstante a opinião dos puristas, um certo pragmatismo pode levar a transigir com este princípio de "Stateless" e armazenar no servidor informações contextuais referentes ao cliente (por exemplo, a identidade do usuário, uma seleção de pasta em curso, etc.). Para evitar solicitar ao requisitante que informe sistematicamente essas informações a cada chamada (ou ao código REST de consultar o banco de dados para recuperar cada vez os mesmos dados), é prático armazená-los temporariamente no servidor e fornecer ao cliente REST um ID de sessão que ele poderá usar novamente e assim permitir ao servidor acessar os dados da sessão.
Esta é a razão de ser da classe lrSession, que oferece métodos para:
- Criar uma sessão
- Verificar a validade da sessão (não expirada)
- Armazenar e ler dados da sessão
- Destruir uma sessão
A classe lrSession implementa os Membros, Constantes e Métodos descritos abaixo.
Membros
Membro | Tipo | Descrição |
---|---|---|
ID | String | Identificador da sessão |
SessionsDirectory | String | Diretório de armazenamento das sessões (por padrão, subdiretório $LR_SESSIONS do executável) |
Códigos de Erro
Código de Erro | Valor | Descrição |
---|---|---|
ErrorSessionExpired | 0x1000 | Sessão expirada |
ErrorSessionIllegal | 0x1001 | Sessão ilegal (ID inválido) |
ErrorSessionCannotLoad | 0x1002 | Impossível carregar os dados da Sessão |
ErrorSessionCannotSave | 0x1003 | Impossível salvar os dados da Sessão |
ErrorSessionCannotSetValue | 0x1004 | Impossível memorizar o valor na Sessão |
ErrorSessionCannotDestroy | 0x1005 | Impossível destruir a Sessão |
ErrorSessionCannotDecypher | 0x1006 | Impossível descriptografar os dados da Sessão |
Métodos
Check() : (booleano, inteiro)
Verificação da sessão: Assinatura válida e sessão que não excedeu o prazo máximo de inatividade (timeout).
Parâmetros: Nenhum
Retorno:
- booleano: Validade do ID de sessão
- inteiro: código de erro
Exemplo:
Procedimento REST com verificação da validade da sessão. O identificador da sessão é passado pelo solicitante em um cabeçalho SESSION_ID da requisição REST.
PROCEDIMENTO REST_TestSession(pRequest é lrRequest) : lrResponse oResponse é lrResponse oSession é lrSession bOK é booleano eErro é inteiro oSession:ID = pRequest::GetHeaderValue("SESSION_ID") (bOK, eErro) = oSession:Check() se bOK então oResponse:Body = "A sessão é válida" oResponse:Status = lrResponse::StatusOK senão oResponse:Body = oSession:GetErrorMessage(eErro) oResponse:Status = lrResponse::StatusUnauthorized //Status HTTP 401 fim oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse
Create(Timeout) : booleano
Criação de uma nova sessão, com expiração automática quando o período de inatividade ultrapassar o parâmetro Timeout. A identificação da sessão inclui uma assinatura que permite detectar o uso de um ID "manipulado" e, portanto, identificar um usuário suspeito (que poderá ser bloqueado com seu endereço IP, por exemplo).
Parâmetro | Tipo | Descrição |
---|---|---|
Timeout | Inteiro | Duração máxima de inatividade da sessão, em Minutos. Após expiração, esta será automaticamente destruída |
Retorno: Booleano. Verdadeiro se a sessão foi criada, Falso se falhou (neste caso, a função ErroInfo() informará o motivo).
Exemplo:
Criação de uma nova sessão que expira após 600 segundos de inatividade. Retorna-se o ID de sessão no cabeçalho HTTP da resposta. O solicitante poderá apresentar este ID em chamadas REST subsequentes.
PROCEDIMENTO REST_CreateSession(pRequest é lrRequest) : lrResponse oSession é lrSession oResponse é lrResponse SE NÃO oSession:Create(600) ENTÃO oResponse:Status = lrResponse::StatusInternalServerError //Erro HTTP 500 oResponse:Body = ErroInfo(errMensagem) SENÃO oResponse:Status = lrResponse::StatusOK oResponse:Body = "Sessão "+oSession:ID+" criada" oResponse:SetHeaderValue("SESSION_ID", oSession:ID) FIM oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse
Destroy() : (booleano, inteiro)
Destrói a sessão atual
Parâmetros: Nenhum
Retorno:
- booleano: Sucesso da destruição
- inteiro: código de erro
Exemplo:
Procedimento REST de destruição da sessão. O identificador da sessão é passado pelo solicitante em um cabeçalho SESSION_ID da requisição REST.
PROCEDIMENTO REST_DestroySession(pRequest é lrRequest) : lrResponse oSession é lrSession oResponse é lrResponse bOK é booleano eErro é inteiro oSession:ID = pRequest::GetHeaderValue("SESSION_ID") (bOK, eErro) = oSession:Destroy() SE NÃO bOK ENTÃO oResponse:Status = lrResponse::StatusUnauthorized //Status HTTP 401 oResponse:Body = oSession:GetErrorMessage(eErro) SENÃO oResponse:Status = lrResponse::StatusOK oResponse:Body = "Sessão "+oSession:ID+" destruída" FIM oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse
GetData(Tag) : (Booleano, *)
Leitura de dados de sessão previamente salvos. O armazenamento de múltiplos dados é previsto, cada um identificado por uma etiqueta (ou Tag).
Parâmetro | Tipo | Descrição |
---|---|---|
Tag | String | Etiqueta do dado de sessão a recuperar |
Retorno:
- Booleano: Sucesso da leitura
- *: Dado conforme escrito durante a chamada ao método SetData
Exemplo:
Leitura dos dados da sessão atual
PROCEDIMENTO REST_ReadSession(pRequest é lrRequest) : lrResponse oSession é lrSession oResponse é lrResponse bOK é booleano eErro é inteiro cData é cadeia oSession:ID = pRequest:GetHeaderValue("SESSION_ID") (bOK, cData) = oSession:GetData("IDADE_DO_CAPITAO") SE NÃO bOK ENTÃO oResponse:Status = lrResponse::StatusInternalServerError //Erro HTTP 500 oResponse:Body = oSession:GetErrorMessage(eErro) oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse FIM oResponse:Body = "A idade do capitão é "+cData oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse
GetErrorMessage(Código de Erro) : String
Recuperação da mensagem de erro correspondente a um código ErrorSession*, no idioma atual. Permite retornar uma mensagem inteligível ao solicitante.
Parâmetro | Tipo | Descrição |
---|---|---|
Código de Erro | Inteiro | Código do erro cuja mensagem se deseja recuperar |
Retorno: String. Mensagem do erro
Veja o exemplo do método Check() que utiliza GetErrorMessage()
Refresh() : (booleano, inteiro)
Atualiza o registro de data/hora do último acesso da sessão. Esta função deve ser chamada quando o usuário realiza uma ação suscetível de reinicializar o prazo de inatividade de sua sessão.
Nota: Os métodos GetData() e SetData() executam automaticamente um Refresh()
Parâmetros: Nenhum
Retorno:
- Booleano: Sucesso ou não da inicialização
- Inteiro: Número do erro
Exemplo:
Tratamento realizando uma atualização da sessão
PROCEDIMENTO REST_FazAlgumaCoisa(pRequest é lrRequest) : lrResponse oSession é lrSession oResponse é lrResponse bOK é booleano eErro é inteiro cData é cadeia oSession:ID = pRequest::GetHeaderValue("SESSION_ID") //Atualizamos a sessão para evitar que ela expire (bOK, eErro) = oSession:Refresh() SE NÃO bOK ENTÃO oResponse:Status = lrResponse::StatusUnauthorized //Status HTTP 401 oResponse:Body = oSession:GetErrorMessage(eErro) oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse FIM ... ... tratamento ... ... oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse
SetCypheringKey(Chave)
Inicializa a chave de criptografia das sessões. Se nenhuma chave foi inicializada, os dados da sessão serão salvos em texto simples no formato JSON.
Atenção, não se deve alterar a chave de criptografia durante a execução, senão os dados de sessão já salvos se tornarão ilegíveis.
Parâmetro | Tipo | Descrição |
---|---|---|
Chave de criptografia | Buffer | Chave de criptografia dos dados de sessão. Na ausência de chave de criptografia, os dados de sessão serão escritos em texto simples no formato JSON |
Retorno: Nenhum
SetData(Tag, Data) : (Booleano, Inteiro)
Escrita de dados de sessão. O armazenamento de múltiplos dados é previsto, cada um identificado por uma etiqueta (ou Tag).
Parâmetro | Tipo | Descrição |
---|---|---|
Tag | String | Etiqueta do dado de sessão a salvar |
Data | Qualquer tipo de dado armazenável em um variant | Dado de sessão a memorizar |
Retorno:
- Booleano: Sucesso da leitura
- Inteiro: Código de Erro
Exemplo:
Escrita dos dados da sessão atual
PROCEDIMENTO REST_WriteSession(pRequest é lrRequest) : lrResponse oSession é lrSession oResponse é lrResponse bOK é booleano eErro é inteiro cData é cadeia oSession:ID = pRequest::GetHeaderValue("SESSION_ID") cData = aleatorio(10,100) (bOK, cData) = oSession:SetData("IDADE_DO_CAPITAO", cData) SE NÃO bOK ENTÃO oResponse:Status = lrResponse::StatusInternalServerError //Erro HTTP 500 oResponse:Body = oSession:GetErrorMessage(eErro) oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse FIM oResponse:Body = "Registramos na sessão a idade do capitão: "+cData oResponse:ContentType = lrResponse::ContentTXT RETORNA oResponse