You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 12, 2020. It is now read-only.
Copy file name to clipboardexpand all lines: README.md
+81-19
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,20 @@
1
1
# redux-http-basic-auth-example
2
2
3
-
4
3
When an app communicates with a HTTP API, which enforces some form of authentication, the app typically follows these steps:
5
4
6
-
1. The app is not authenticated, so the user is prompted to log in.
7
-
2. The user enters their username and password, and taps submit.
8
-
3.The credentials are sent to the API, and the app inspects the response:
9
-
4. On success (200 - OK): The authentication token or hash is cached, the app uses this token in every subsequent request.
10
-
5. If at any stage, during an API request, the hash or token doesn't work anymore (401 - Unauthorized), then the user is prompted to re-enter their credentials.
11
-
6.On failure (401 - Unauthorized): The client displays an error message to the user, prompting them re-enter their credentials.
5
+
1. The app is not authenticated, so we prompt the user to log in.
6
+
2. The user enters their credentials (username and password), and taps submit.
7
+
3.We send these credentials to the API, and inspect the response:
8
+
4. On success (200 - OK): We cache the authentication token/ hash, because we're going to use this token/ hash _in every subsequent_ request.
9
+
5. If the token/ hash does not work during any of the subsequent API requests (401 - Unauthorized), we'll need to invalidate the hash/ token and prompt the user to log in again.
10
+
6.Or, on failure (401 - Unauthorized): We display an error message to the user, prompting them re-enter their credentials.
12
11
13
-
Based on the work flow defined above we start our app by displaying a login form, _step 2_ kicks in when the user taps the login button...
12
+
Based on the work flow defined above we start our app by displaying a login form, _step 2_ kicks in when the user taps the login button... Dispatching the `login` action creator:
14
13
15
14
# Logging In #
16
15
16
+
Let's jump into some code:
17
+
17
18
```
18
19
/// actions/user.js
19
20
@@ -25,9 +26,10 @@ export function login(username, password) {
25
26
// view.
26
27
dispatch(loginRequest())
27
28
28
-
// This only works in Node, use an implementation that work for the
29
-
// platform you're using, e.g.: `base64-js` for React Native, or `btoa()`
30
-
// for browsers, etc...
29
+
// Note: This base64 encode method only works in NodeJS, so use an
30
+
// implementation that works for your platform:
31
+
// `base64-js` for React Native,
32
+
// `btoa()` for browsers,
31
33
const hash = new Buffer(`${username}:${password}`).toString('base64')
@@ -54,15 +56,16 @@ export function login(username, password) {
54
56
}
55
57
```
56
58
57
-
There's a lot going on in the function above, but take comfort in the fact that
58
-
the vast majority of the code is sanitizing the request process and can be abstracted away.
59
-
59
+
There's a lot of code in the function above, but take comfort in the fact that
60
+
the majority of the code is sanitizing the request and can be abstracted away.
60
61
62
+
The first thing we do is dispatch an action creator:
61
63
```
62
64
dispatch(loginRequest())
63
65
```
64
-
Updates our Redux store, by setting a `isLoggingIn` property to `true`, this is used to display a loading indicator and disable the login button.
66
+
Which results in our state letting us know that the user `isLoggingIn`. We use this to display an activity indicator (_spinning wheel_), and to disable the log in button in our log in view.
65
67
68
+
Next we base64 encode our credentials, and setup a fetch request.
66
69
```
67
70
const hash = new Buffer(`${username}:${password}`).toString('base64')
Our example uses HTTP basic access authentication, so we've generated a base64 hash from the `username` and `password` and added the `Authorization` headers to our request.
75
77
78
+
Everything went well, so we...
76
79
```
77
80
dispatch(loginSuccess(hash, data.user))
78
81
```
79
-
If everything went well then we dispatch the `LOGIN_SUCCESS` action along with our`hash`and `user` object. The `hash` is used in subsequent API requests.
82
+
Our `LOGIN_SUCCESS` action results in the`hash`been stored in our state, which will be used in every subsequent request.
80
83
84
+
If something went wrong then we want to let the user know...
81
85
```
82
86
dispatch(loginFailure(data.error || 'Log in failed')
83
87
```
84
-
If the request failed then we need to update the login view, removing the loading indicator, enabling the submit button, and displaying an error message.
85
88
86
89
_The `loginSuccess`, `loginFailure`, and `loginRequest` action creators are fairly generic and don't really warrant code samples. (See `actions/user.js`)_
87
90
88
91
### Reducer ###
89
92
93
+
Our reducer is fairly typical, simply updating our store for each action it receives.
94
+
90
95
```
91
96
/// reducers/user.js
92
97
@@ -121,4 +126,61 @@ function user(state = {
121
126
122
127
# Subsequent API requests #
123
128
124
-
Now that we have a authentication `hash` in our store.
129
+
We now have an authentication hash in our store, which we can use in subsequent action creators on requests.
// did our request fail because our auth credentials aren't working?
161
+
if (response.status == 401) {
162
+
dispatch(loginFailure(data.error))
163
+
}
164
+
}
165
+
)
166
+
}
167
+
}
168
+
```
169
+
170
+
You'll find that most API requests typically dispatches the same 3 actions as above: `API_REQUEST`, `API_SUCCESS`, and `API_FAILURE`, and as such the majority of the request/ response code can be pushed into [middleware](https://github.com/reactjs/redux/issues/99#issuecomment-112198579).
We fetch the hash authentication token from the store and setup the request. If our API requests with a 401 unauthorized status code then we've got to remove our hash from the store, and present the user with a log in view.
181
+
```
182
+
// did our request fail because our auth credentials aren't working?
0 commit comments