Skip to content

Commit 72bb933

Browse files
authored
Merge pull request #13 from kirillplatonov/request-interceptor
Add request interceptor support
2 parents affb372 + 163901a commit 72bb933

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,28 @@ import { Turbo } from "@hotwired/turbo-rails"
4444
window.Turbo = Turbo
4545
```
4646

47+
#### Request Interceptor
48+
49+
To authenticate fetch requests (eg. with Bearer token) you can use request interceptor. It allows pausing request invocation for fetching token and then adding it to headers:
50+
51+
```javascript
52+
import { RequestInterceptor } from '@rails/request.js'
53+
// ...
54+
55+
// Set interceptor
56+
RequestInterceptor.register(async (request) => {
57+
const token = await getSessionToken(window.app)
58+
request.addHeader('Authorization', `Bearer ${token}`)
59+
})
60+
61+
// Reset interceptor
62+
RequestInterceptor.reset()
63+
```
64+
4765
# Known Issues
4866

4967
`FetchRequest` sets a `"X-Requested-With": "XmlHttpRequest"` header. If you have not upgraded to Turbo and still use `Turbolinks` in your Gemfile, this means
50-
you will not be able to check if the request was redirected.
68+
you will not be able to check if the request was redirected.
5169

5270
```js
5371
const request = new FetchRequest('post', 'localhost:3000/my_endpoint', { body: { name: 'Request.JS' }})

src/fetch_request.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FetchResponse } from './fetch_response'
2+
import { RequestInterceptor } from './request_interceptor'
23
import { getCookie } from './lib/cookie'
34

45
export class FetchRequest {
@@ -9,6 +10,14 @@ export class FetchRequest {
910
}
1011

1112
async perform () {
13+
try {
14+
const requestInterceptor = RequestInterceptor.get()
15+
if (requestInterceptor) {
16+
await requestInterceptor(this)
17+
}
18+
} catch (error) {
19+
console.error(error)
20+
}
1221
const response = new FetchResponse(await window.fetch(this.url, this.fetchOptions))
1322
if (response.unauthenticated && response.authenticationURL) {
1423
return Promise.reject(window.location.href = response.authenticationURL)
@@ -18,6 +27,12 @@ export class FetchRequest {
1827
}
1928
}
2029

30+
addHeader (key, value) {
31+
const headers = this.additionalHeaders
32+
headers[key] = value
33+
this.options.headers = headers
34+
}
35+
2136
get fetchOptions () {
2237
return {
2338
method: this.method.toUpperCase(),

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { FetchRequest } from './fetch_request'
22
import { FetchResponse } from './fetch_response'
3+
import { RequestInterceptor } from './request_interceptor'
34

4-
export { FetchRequest, FetchResponse }
5+
export { FetchRequest, FetchResponse, RequestInterceptor }

src/request_interceptor.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export class RequestInterceptor {
2+
static register (interceptor) {
3+
this.interceptor = interceptor
4+
}
5+
6+
static get () {
7+
return this.interceptor
8+
}
9+
10+
static reset () {
11+
this.interceptor = undefined
12+
}
13+
}

0 commit comments

Comments
 (0)