Validade das credenciais SSO / logout forçado

Que expectativa devo ter sobre por quanto tempo um usuário pode permanecer logado antes de ser solicitado a fazer login novamente?

Implementei minha própria verificação no functions.php, integrando ao plugin SSO para WordPress. Minha lógica parece bastante simples, mas notei que um membro que teve o cartão de crédito recusado (o que removeu a tag de usuário que minha lógica verifica) conseguiu acessar meu fórum hoje. Ao verificar mais detalhadamente, descobri que ela fez o último login há alguns dias e, suponho, ainda parece estar logada. A data do último login dela no WordPress também é de alguns dias atrás.

É esperado que as credenciais em cache dela ainda estejam funcionando? Se sim, há alguma maneira de controlar a validade do token e/ou responder a um webhook para forçar o logout?

Obrigado.

Isso é controlado pela configuração do site “maximum session age” (idade máxima da sessão) do Discourse. Ela define o número de horas que os usuários permanecerão logados no seu site. O valor padrão é de 1440 horas (60 dias). Você pode tentar definir esse valor para um número menor. Se definir muito baixo, pode parecer um bug para seus usuários.

Isso faz sentido. Você pode fazer logout dos usuários manualmente acessando a página de Administração do Discourse deles e clicando no botão “Log Out” que você verá no canto superior direito da página. Outra opção para controlar isso seria adicionar algum código ao seu site WordPress que faça o logout dos usuários do Discourse quando uma associação expirar.

Muito obrigado, Simon. Embora eu ache que 60 dias seja muito longo para os meus cenários (estes são membros pagantes, então eles esperam que verifiquemos se ainda são membros válidos), concordo que reduzi-lo demais pode ser problemático.

A sugestão final (encontrar uma maneira de desconectá-los do Discourse quando a assinatura terminar) é o que vou pesquisar. Eu já havia visto a opção de desconexão manual, mas estou buscando automatizar tudo completamente, então isso parece ser o caminho certo.

Obrigado novamente.

Hmm… a descrição da configuração do site diz (ênfase minha):

O usuário permanecerá logado por n horas desde a última visita

Se eu entendi corretamente, eles poderiam permanecer logados para sempre se continuarem visitando o site periodicamente, mesmo após perderem suas credenciais de SSO. Por exemplo, se a configuração estiver definida para 72 horas, desde que continuem visitando o site a cada dia ou dois, eles permanecerão logados. Estou interpretando isso corretamente?

Sim, isso é verdade na minha experiência. Não há um tempo limite absoluto que force o logout de alguém após um período fixo de tempo.

Então, a implicação disso é que, se alguém cancelar minha assinatura e eu quiser ter certeza de que não poderão acessar meu fórum, terei que desconectá-los à força (manualmente ou por meio de uma chamada de API)?

Sim, essa é a recomendação.

Obrigado. Acabei de migrar de um grupo do Facebook (que exigia a remoção manual de membros quando eles cancelavam suas assinaturas), e é lamentável que, com o Discourse, ainda precise de um processo manual para garantir que membros cancelados não acessem meu fórum. Isso leva a uma pergunta.

Existe algum mecanismo não manual — por mais criativo que seja — que garanta que um usuário sem conta válida, ou seja, que não consegue fazer login, seja desconectado forçadamente do Discourse?

Parece logicamente estranho que o mecanismo de SSO bloqueie o login de usuários (reconhecendo que eles não têm uma conta válida), mas se eles acessam o fórum regularmente (menos que o tempo limite de sessão), podem permanecer acessando o fórum indefinidamente, até que eu os desconecte manualmente.

Acho que minha última opção, potencialmente, é escrever um plugin que chame a API do Discourse para desconectá-los quando cancelarem.

Estou aberto a todas as ideias possíveis. Como podem perceber, REALMENTE quero evitar ter que fazer isso manualmente :slight_smile:

Obrigado.

Você pode fazer uma solicitação de API para /admin/users/<discourse_user_id>/log_out. O plugin WP Discourse usa essa rota para sincronizar o logout do WordPress com o Discourse. Você provavelmente pode copiar a maior parte do código desta função: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub.

Muito obrigado, Simon. Vou dar uma olhada.

Mas, pensando de forma mais ampla, isso não parece ser um problema? Suponho que possamos debater a importância disso, mas ter uma plataforma onde os usuários podem continuar acessando um fórum indefinidamente, mesmo quando não têm mais uma conta válida, é algo que não tenho visto em outros lugares.

Talvez eu possa aceitar a ideia de que é o WordPress, e não o Discourse, que é a fonte de verdade aqui. Isso provavelmente aponta para o plugin SSO como o melhor lugar para implementar alguma lógica.

Tenho curiosidade em saber o raciocínio geral por trás disso. Gostaria de pensar que esse cenário é válido (forçar o logout após um certo período de tempo ou com base em uma conta do WordPress tornando-se “inválida”), não é?

Estou apenas fazendo um brainstorming aqui, pois gostaria de evitar etapas manuais, mas também quero evitar escrever código, se possível :slight_smile:

Sim, isso precisará ser tratado pelo WordPress. Acredito que faria sentido que o plugin WP Discourse desconectasse os usuários do Discourse quando eles fossem excluídos no WordPress, mas não tenho certeza se isso resolveria seu problema. Minha suposição é que, quando a assinatura de um usuário expira em seu site, o usuário não é excluído do seu site WordPress. Para lidar com o caso de desconectar um usuário do Discourse quando sua assinatura expira, você provavelmente precisará adicionar algum código ao seu site que se conecte à ação acionada pelo seu plugin de assinatura quando uma assinatura expira.

Obrigado novamente, @simon. Seus pontos fazem sentido, mas me perdoe se eu continuar por mais uma rodada :slight_smile:

Parece que há dois fatores em jogo aqui: a validade de uma conta (ou seja, se a pessoa é um membro ativo) e a validade de um token no Discourse.

Quanto ao primeiro, concordo plenamente que o WordPress deve ser o responsável por isso e, conforme o tempo permitir, vou investigar.

No entanto, também há a questão de um token ativo/válido do lado do Discourse. Entendo que isso pode não ser uma prioridade alta, mas vejo algum sentido em ter uma opção (provavelmente desativada por padrão) com um período de “forçar login”, ou seja, após x dias o token de login do usuário expira, independentemente de ter feito login recentemente ou não.

Mais uma vez, estou apenas brainstormando aqui, mas consigo ver algum valor em forçar um logout como uma opção, independentemente de o usuário ter uma conta válida.

Estou tentando fazer isso por meio de um link da web, pois não estou usando o WordPress. Deveria ser possível fazer isso com algo assim?

https://community.mysite.com/admin/users/100004/log_out

Para mim, isso resulta em um erro 404 e o usuário não é deslogado.

Se eu conseguir fazer uma URL funcionar, espero forçar o logout usando um comando curl ou file_get_contents no PHP…

Você precisa fazer uma requisição POST autenticada para a rota. Você pode configurar isso para desconectar os usuários quando eles clicarem em um link, mas precisará lidar com a requisição no servidor.

Obrigado! Autenticado, hein? Estou pesquisando sobre isso e parece que uma postagem autenticada do PHP envia algo assim no cabeçalho:

'Authorization: OAuth '.$accesstoken;

Existem algumas pistas por aí que continuarei a pesquisar.

Mas seria ótimo se alguém tivesse um trecho de código PHP que funcionasse! O exemplo na seção de autenticação de https://docs.discourse.org/ retorna um erro de sintaxe para mim… oh, espere, isso é um comando Unix!

Agradeço qualquer pista que ajude com PHP!

O link da minha postagem anterior deve ser suficiente para você começar: wp-discourse/lib/sso-provider/discourse-sso.php at main · discourse/wp-discourse · GitHub. Supondo que você não esteja fazendo a solicitação a partir de um site WordPress, precisará descobrir outra maneira de fazer a solicitação wp_remote_post.

Acho que estou perto, usando comandos PHP simples. O código está abaixo. A escolha do nome de usuário veio deste post.

Estou recebendo esta resposta… isso significa algo para alguém? Parece ser algo relacionado à versão do protocolo SSL?

error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

Aqui está meu código:

    $url = "https://community.mysite.com/admin/users/100004/log_out";
    $headers = array( 'Api-Key' => 'd412mylongadminkeyaadcd',
                    'Api-Username' => 'system',
                    );

	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);

[edit: adicionei essas linhas também, sem alteração:]
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
[/edit]

	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $data = curl_exec($ch);
    if (curl_errno($ch)) {
        echo curl_error($ch);
    }
    curl_close($ch);

Como você está no WordPress, pode tentar fazer a requisição com a função wp_remote_post. Assim, você não precisa lidar com as opções do curl.

Obrigado, mas não estou usando WordPress. Estou tentando fazer isso em PHP, em um gerenciador de assinaturas que desenvolvi ao longo da última década.

Parece que sua biblioteca PHP não gostou do certificado HTTPS do seu Discourse. Pesquise esse erro no Google.