Use o Amigo para autenticação e autorização em uma única página do aplicativo da web Clojure

Eu estou tentando integrar autenticação e autorização de amigo em um aplicativo da Web de uma página Clojure / Compojure.

Eu tenho um formulário de login apoiado por um controlador Angular, e este controlador usa AJAX para autenticar o nome de usuário e senha contra o aplicativo da web e obter um registro de usuário autenticado. Por causa disso, eu não quero o comportamento padrão fornecido pelo login baseado em formulários do Google Friend. Basicamente, quero confiar nos códigos de status HTTP enão quer qualquer um dos redirecionamentos da página do amigo.

Por exemplo, fazer uma solicitação não autenticada deve simplesmente retornar um código de status 401 e não redirecionar para "/ login". Eu tenho esta parte trabalhando, especificando um personalizado ": manipulador não autenticado" ao configurar o amigo (código incluído abaixo).

Em um login bem-sucedido, eu simplesmente quero um código de status 200 e não um redirecionamento para a página originalmente solicitada. Isto é o que eu não consigo trabalhar.

Escrevi um fluxo de trabalho personalizado de autenticação de amigos com base nos vários exemplos (minhas habilidades de Clojure são de nível iniciante agora):

(defn my-auth
  [& {:keys [credential-fn]}]
    (routes
      (GET "/logout" req
        (friend/logout* {:status 200}))
      (POST "/login" {{:keys [username password]} :params}
        (if-let [user-record (-> username credential-fn)]
          (if
            (and
              [user-record password]
              (creds/bcrypt-verify password (:password user-record)))
            (let [user-record (dissoc user-record :password)]
              (workflows/make-auth user-record {:cemerick.friend/workflow :my-auth :cemerick.friend/redirect-on-auth? true}))
            {:status 401})
          {:status 401}))))

Aqui está meu manipulador com middlewares declarados:

(def app
  (-> 
    (handler/site
      (friend/authenticate app-routes
        {:credential-fn (partial creds/bcrypt-credential-fn my-credential-fn)
         :unauthenticated-handler unauthenticated
         :workflows [(my-auth :credential-fn my-credential-fn)]}))
    (session/wrap-session)
    (params/wrap-keyword-params)
    (json/wrap-json-body)
    (json/wrap-json-response {:pretty true})))

E a função de manipulador adicional referenciada pelo acima:

(defn unauthenticated [v]
  {:status 401 :body "Unauthenticated"})

Finalmente, um fragmento de rotas adicionais para testar a autenticação:

(GET "/auth" req
  (friend/authenticated (str "You have successfully authenticated as "
    (friend/current-authentication))))

estena maioria das vezes funciona equase faz tudo que preciso.

Porque "redirect-on-auth?" é verdade em "make-auth", em um login bem-sucedido, um redirecionamento de página é gerado - eu quero evitar esse redirecionamento, então eu defino o valor como false. No entanto, essa única alteração resulta em um login com falha e 404.

Portanto, assim como o mapa de autenticação do Google Friend, preciso retornar um código de status 200 e também quero retornar o "registro de usuário" no corpo da resposta para que o aplicativo cliente possa adaptar a interface do usuário, dependendo das funções do usuário já tem solicitações / respostas JSON embrulhadas e funcionando).

Então eu acho que preciso do equivalente a isso quando invoco a função "make-auth" do Friend:

{:status 200 :body user-record}

No entanto, parece que posso ter o mapa de autenticação ou a resposta - mas não os dois juntos.

Isso pode ser conseguido com o amigo e se sim como?

questionAnswers(2)

yourAnswerToTheQuestion