-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmiddleware.html
More file actions
107 lines (106 loc) · 8.43 KB
/
Copy pathmiddleware.html
File metadata and controls
107 lines (106 loc) · 8.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title>Coast on Clojure</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="/favicon.png" rel="icon" type="image/png">
<link rel="stylesheet" href="/bundle--6885699.css" />
</head>
<body>
<nav class="dt w-100 border-box pa3 ph5-ns">
<a class="dtc v-mid near-black link dim w-25" href="/" title="Home">
<img alt="Coast on Clojure" class="dib w2 h2 br-100" src="/favicon.png">
<span class="ml2 v-top mt2 dib near-black">Coast</span>
</a>
<div class="dtc v-mid w-75 tr">
<a class="link dim near-black f6 f5-ns dib mr3 mr4-ns" href="/docs" title="Docs">Docs</a>
<a class="link dim near-black f6 f5-ns dib mr3 mr4-ns" href="https://twitter.com/coastonclojure" title="Twitter">Twitter</a>
<a class="link dim near-black f6 f5-ns dib" href="https://github.com/coast-framework/coast" title="Github">Github</a>
</div>
</nav>
<div class="grid bg-nearest-white">
<div class="pa4 bg-nearest-white sidebar-container">
<div class="fr-l sidebar">
<h3 id="user-content-preface">Preface</h3>
<ul>
<li><a href="/docs/about">About</a></li>
<li><a href="/docs/credits">Credits</a></li>
<li><a href="/docs/upgrading">Upgrading from eta</a></li>
<li><a href="/docs/contribution">Contribution Guide</a></li>
</ul>
<h3 id="user-content-concept">Concept</h3>
<ul>
<li><a href="/docs/request-lifecycle">Request Lifecycle</a></li>
</ul>
<h3 id="user-content-getting-started">Getting Started</h3>
<ul>
<li><a href="/docs/installation">Installation</a></li>
<li><a href="/docs/configuration">Configuration</a></li>
<li><a href="/docs/directory-structure">Directory Structure</a></li>
</ul>
<h3 id="user-content-database">Database</h3>
<ul>
<li><a href="/docs/database-getting-started">Getting Started</a></li>
<li><a href="/docs/queries">Queries</a></li>
<li><a href="/docs/migrations">Migrations</a></li>
<li><a href="/docs/relationships">Relationships</a></li>
<li><a href="/docs/pull">Pull</a></li>
</ul>
<h3 id="user-content-basics">Basics</h3>
<ul>
<li><a href="/docs/routing">Routing</a></li>
<li><a href="/docs/middleware">Middleware</a></li>
<li><a href="/docs/handlers">Handlers</a></li>
<li><a href="/docs/request">Request</a></li>
<li><a href="/docs/response">Response</a></li>
<li><a href="/docs/views">Views</a></li>
<li><a href="/docs/sessions">Sessions</a></li>
<li><a href="/docs/validator">Validator</a></li>
<li><a href="/docs/error-handling">Error Handling</a></li>
<li><a href="/docs/logger">Logger</a></li>
</ul>
<h3 id="user-content-security">Security</h3>
<ul>
<li><a href="/docs/security-intro">Introduction</a></li>
<li><a href="/docs/authentication">Authentication</a></li>
<li><a href="/docs/csrf-protection">CSRF Protection</a></li>
<li><a href="/docs/password-hashing">Password Hashing</a></li>
<li><a href="/docs/security-outro">XSS, Sniffing, XFrame</a></li>
</ul>
<h3 id="user-content-miscellaneous">Miscellaneous</h3>
<ul>
<li><a href="/docs/older-versions">Older Versions</a></li>
</ul>
</div>
</div>
<div class="ph4 bg-white content">
<h1 id="user-content-middleware">Middleware</h1><ul><li><a href='#user-content-creating-middleware'>Creating Middleware</a></li><li><a href='#user-content-using-middleware'>Using Middleware</a></li><li><a href='#user-content-route-middleware'>Route Middleware</a></li><li><a href='#user-content-middleware-options'>Middleware Options</a></li></ul><p>Middleware hook into the request lifecycle of your application.</p><p>They are a set of functions executed in sequence and let you transform the request and/or the response.</p><p>As an example, Coast provides several middleware functions inside of the <code>app</code> function.</p><h2 id="user-content-creating-middleware">Creating Middleware</h2><p>To create a new middleware, Coast's convention is to define a <a href='https://github.com/ring-clojure/ring/wiki/Middleware-Patterns'>ring middleware</a> function in the <code>src/middleware.clj</code> file</p><pre><code class="clojure">(ns middleware
(:require [coast]))
(defn auth [handler]
(fn [request]
(if (some? (:session request))
(handler request)
(coast/unauthorized "No"))))
</code></pre><p>In the example <code>auth</code> middleware, we want to show a 401 unauthorized response if there is no session</p><h3 id="user-content-middleware-execution-order">Middleware Execution Order</h3><p>When your middleware function gets called, you can modify the request or the response like this:</p><pre><code class="clojure">(defn your-middleware [handler]
(fn [request]
; request == {:request-method :get :uri "/" :headers {} :params {}}
(let [request (merge request {:hello "world"})
response (handler request)]
; response == {:status 200 :body "" :headers {"content-type" "text/html"}}
(assoc response :status 404))))
</code></pre><p>All middleware referenced "below" your handler function modifies the request before your function and then it modifies the response after your function is called.</p><p>In fact, while coast is a "web app framework", the <code>app</code> function is really just made up of a series of ring middleware, like this:</p><h3 id="user-content-route-middleware">Route Middleware</h3><p>Route middleware can modify the request before the functions you write and modify the response map after.</p><p>Even <code>404</code>'s are middleware functions that come from <code>(coast/site)</code>.</p><p>Coast calls one function on every route defined underneath <code>site</code>:</p><pre><code class="clojure">(def routes
(coast/site
(coast/with-layout :layout-fn
[:get "/posts" :post/index]
[:post "/posts" :post/create])))
</code></pre><h4 id="user-content-<code>site</code>"><code>site</code></h4><p>This function wraps the routes underneath it in csrf protection, sessions, cookies and flash messages.</p><h4 id="user-content-<code>with-layout</code>"><code>with-layout</code></h4><p>This function wraps all of the routes below it in the layout function defined which takes two arguments, the request and the response from your handler function</p><h3 id="user-content-middleware-options">Middleware Options</h3><p>Coast can receive several options to the various middleware functions.</p><pre><code class="clojure">(coast/app {:storage "/path/to/your/files"})
</code></pre><p>Those two are the most common keys that coast can be configured with:</p><h4 id="user-content-<code>:storage</code>"><code>:storage</code></h4><p>This is the path to where user uploaded files can be served from, so you might want to put this in an environment variable and reference it if you need to store user uploaded things.</p><h4 id="user-content-<code>:session</code>"><code>:session</code></h4><p>The session key can be modified from <code>coast/site</code> like so:</p><pre><code class="clojure">(coast/site {:session {:cookie-attrs {:max-age 2629800}}}
[:get "/" ::index])
</code></pre><p>There are multiple keys you can pass to the <code>:session</code> key, but <code>cookie-attrs</code> is the most common one. You can adjust how long a given person can stay logged into your site, the cookies' name in their browsers, anything about the <a href='https://github.com/ring-clojure/ring/wiki/Sessions'>ring session cookie store</a>, really.</p>
</div>
</div>
<script type="text/javascript" src="/bundle-2017277981.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>