duct

Danny Almeida 2020-02-14T01:28:01.047200Z

Noob here.. I'm trying out duct example here <https://circleci.com/blog/build-a-clojure-web-app-using-duct/>. Everything works splended! So, I added a new handler to delete a film ..just as basic handler which takes a movie name and calls jdbc/execute to delete the record. But when I try to call it using httpie I get an error "Invalid anti-forgery token". The config uses :duct.module.web/site which sets the :anti-forgery key to true under :duct.middleware.web/defaults . I suspect this is the cause of the error. Is there any way to disable the check only for DELETE ..since delete is not called from a form but rather from the list of films being displayed on the page. Or is there a better way of doing this ? Hope I'm making sense 🙂

Danny Almeida 2020-02-14T08:57:05.047500Z

Thank you for the suggestion..right now this is a simple server side rendered html page ..no javascript and no XHR ..just simple rest based calls. For now I've changed the settings in config.edn to :duct.module.web/api key and that works. I am using httpie command line tool to do quick testing of api calls instead and once that works, then I setup the UI part of it. Is there any way to change the keys in config.edn ? Cause :duct.module.web/api takes a map, but I'm not sure how to specify options.

g7s 2020-02-14T09:04:31.047800Z

What you did works because :duct.module.web/api does not include anti forgery protection, but you eventually have to implement. If this is a web app then I recommend sticking with :duct.module.web/site

1
g7s 2020-02-14T09:05:55.048Z

The page is going to make these DELETE calls how? Through XHR or through form submission?

1
Danny Almeida 2020-02-14T09:07:53.048200Z

Yes I understand that. This is just for a quick test before coding the UI. I wouldn't want the web app to use :duct.module.web/api. But for now it makes my life a bit easier 😊

Danny Almeida 2020-02-14T09:08:22.048400Z

Right now it's a form based call

g7s 2020-02-14T09:09:44.048600Z

If you want to be able to use httpie for manual testing then render the token in the html form in a hidden field and copy its value then pass it in a header in that httpie call you want to make. That's all :) ofc do whatever works for you!

1
Danny Almeida 2020-02-14T09:09:48.048800Z

But later I'm planning to use clojurescript to make the calls

Danny Almeida 2020-02-14T09:10:30.049Z

Thanks. Will check it out

👍 1
Danny Almeida 2020-02-14T09:21:26.049400Z

I'm taking one step at a time.. as part of learning Graph APIs, I want to use pathom with duct on the back-end and fulcro for the front-end..but will be at a later stage 🙂

g7s 2020-02-14T06:40:33.047300Z

Well the best practice is to make the DELETE to also pass the anti forgery token. This means that you must have the token in the lists page. You can accomplish that by embedding the token in a meta tag and retrieve it through JS (assuming that the calls are done with XHR).

1
d0c0nnor 2020-02-14T14:48:53.051700Z

Hi, just trying to use Aleph and Yada from duct - I'm getting the error below, which I assume is because returning a manifold deferred is breaking the default middleware. Is there a way that I can switch off the default middleware ?

java.lang.ClassCastException: class manifold.deferred.Deferred cannot be cast to class clojure.lang.Associative (manifold.deferred.Deferred is in unnamed module of loader clojure.lang.DynamicClassLoader @237563b0; clojure.lang.Associative is in unnamed module of loader 'app')
                   RT.java:823 clojure.lang.RT.assoc
                  core.clj:191 clojure.core/assoc
                 core.clj:6169 clojure.core/assoc-in
                 core.clj:6161 clojure.core/assoc-in
               response.clj:79 ring.util.response/header
               response.clj:76 ring.util.response/header
              response.clj:180 ring.util.response/content-type
              response.clj:176 ring.util.response/content-type
           content_type.clj:16 ring.middleware.content-type/content-type-response

2020-02-14T14:49:54.051800Z

Yes, you can override the middleware. If you print out the config variable in the REPL, you can see all the middleware that is added by the web module.

2020-02-14T14:51:19.052Z

Alternatively, you can write a wrapper around your handler that converts it from an Aleph-compatible handler to a Ring-compatible handler, then write another middleware that converts it back before it hits Aleph.

d0c0nnor 2020-02-14T15:12:36.052200Z

Ok, thanks, so I assume that this is the key that I want to override ?

:duct.handler/root
 {:router {:key :duct/router},
  :middleware
  [{:key :duct.middleware.web/not-found}
   {:key :duct.middleware.web/defaults}
   {:key :duct.middleware.web/log-requests}
   {:key :duct.middleware.web/log-errors}
   {:key :duct.middleware.web/stacktrace}]}
Should I expect this to work ?
:duct.handler/root {:middleware []}
When added to my base profile ? Thanks for your help.

d0c0nnor 2020-02-14T16:12:04.052400Z

FYI in the end I switched off the web module and just used the web server key. Thanks for you help!