Skip to content
This repository was archived by the owner on Mar 22, 2022. It is now read-only.

Commit b65db07

Browse files
committed
Added a short tutorial to the README introduction.
This updates the example in the README to use the new feathers-mongoose syntax and provides a few jquery examples to better show how it works. It'll save some people a few minutes by giving an example of how to use jQuery.ajax to send the custom Authorization header in the request.
1 parent 0cf77ad commit b65db07

1 file changed

Lines changed: 120 additions & 20 deletions

File tree

README.md

Lines changed: 120 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,154 @@
1010
If you are using the default options, setting up JWT auth for your Feathers app is as simple as the below example. Note: You must set up the `body-parser` module before setting up `feathers-authentication`.
1111

1212
```js
13+
/* * * Import Feathers and Plugins * * */
1314
var feathers = require('feathers');
1415
var hooks = require('feathers-hooks');
1516
var bodyParser = require('body-parser');
1617
var feathersAuth = require('feathers-authentication').default;
1718
var authHooks = require('feathers-authentication').hooks;
19+
20+
/* * * Prepare the Mongoose service * * */
1821
var mongooseService = require('feathers-mongoose');
22+
var mongoose = require('mongoose');
23+
var Schema = mongoose.Schema;
24+
var UserSchema = new Schema({
25+
username: {type: String, required: true, unique: true},
26+
password: {type: String, required: true },
27+
createdAt: {type: Date, 'default': Date.now},
28+
updatedAt: {type: Date, 'default': Date.now}
29+
});
30+
var UserModel = mongoose.model('User', UserSchema);
31+
32+
/* * * Connect the MongoDB Server * * */
33+
mongoose.Promise = global.Promise;
34+
mongoose.connect('mongodb://localhost:27017/feathers');
1935

36+
/* * * Initialize the App and Plugins * * */
2037
var app = feathers()
2138
.configure(feathers.rest())
2239
.configure(feathers.socketio())
2340
.configure(hooks())
41+
.use(bodyParser.json())
2442
.use(bodyParser.urlencoded({ extended: true }))
43+
2544
// Configure feathers-authentication
2645
.configure(feathersAuth({
2746
secret: 'feathers-rocks'
28-
}))
29-
.use('/api/users', new mongooseService('user', {
30-
schema: {
31-
email: {type: String, required: true, unique: true },
32-
password: {type: String, required: true },
33-
admin: {type: Boolean, default: false }
34-
},
35-
before:{
36-
create: [authHooks.hashPassword('password')]
37-
}
38-
}))
39-
47+
}));
48+
49+
/* * * Setup the User Service and hashPassword Hook * * */
50+
app.use('/api/users', new mongooseService('user', UserModel))
51+
var service = app.service('/api/users');
52+
service.before({
53+
create: [authHooks.hashPassword('password')]
54+
});
55+
56+
/* * * Start the Server * * */
57+
var port = 3030;
58+
var server = app.listen(port);
59+
server.on('listening', function() {
60+
console.log(`Feathers application started on localhost:3030);
61+
});
4062
```
4163

42-
### REST Requests
43-
Authenticated REST requests must have an `Authorization` header in the format `'Bearer <token>'`, where the <token> is the JWT token. For example:
64+
Please note that the above User service does not include any kind of authorization or access control. That will require setting up additional hooks, later. For now, leaving out the access control will allow us to easily create a user. Here's an example request to create a user (make sure your server is running):
65+
66+
```js
67+
// Create User (POST http://localhost:3030/api/users)
68+
jQuery.ajax({
69+
url: 'http://localhost:3030/api/users',
70+
type: 'POST',
71+
headers: {
72+
'Content-Type': 'application/json',
73+
},
74+
contentType: 'application/json',
75+
data: JSON.stringify({
76+
'username': 'feathersuser',
77+
'password': 'fowlplay'
78+
})
79+
})
80+
.done(function(data, textStatus, jqXHR) {
81+
console.log('HTTP Request Succeeded: ' + jqXHR.status);
82+
console.log(data);
83+
})
84+
.fail(function(jqXHR, textStatus, errorThrown) {
85+
console.log('HTTP Request Failed', arguments);
86+
});
87+
```
88+
89+
Once you've created a user, logging in is as simple as `POST`ing a request to the `loginEndpoint`, which is `/api/login` by default. Here's an example request for logging in:
90+
91+
```js
92+
// Login by email (POST http://localhost:3030/api/login)
93+
jQuery.ajax({
94+
url: 'http://localhost:3030/api/login',
95+
type: 'POST',
96+
headers: {
97+
'Content-Type': 'application/json',
98+
},
99+
contentType: 'application/json',
100+
data: JSON.stringify({
101+
'username': 'feathersuser',
102+
'password': 'fowlplay'
103+
})
104+
})
105+
.done(function(data, textStatus, jqXHR) {
106+
console.log('HTTP Request Succeeded: ' + jqXHR.status);
107+
console.log(data);
108+
})
109+
.fail(function(jqXHR, textStatus, errorThrown) {
110+
console.log('HTTP Request Failed', arguments);
111+
});
112+
```
113+
The server will respond with an object that contains two properties, `user` and `token`. The `user` property contains an object with whatever data was returned from your user service. You'll notice that it currently includes the password. You really don't want it exposed, so when you're ready to secure the service, you'll need an additional feathers-hook to remove the password property from the response.
114+
115+
The `token` property contains a JWT token that you can use to authenticate REST requests or for socket connections. You can learn more about how JWT tokens work on [jwt.io](http://jwt.io/).
116+
117+
118+
### Authenticating REST Requests
119+
120+
Authenticated REST requests must have an `Authorization` header in the format `'Bearer <token>'`, where the <token> is the JWT token. The header should have the following format:
44121
```
45122
Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IklseWEgRmFkZWV2IiwiYWRtaW4iOnRydWV9.YiG9JdVVm6Pvpqj8jDT5bMxsm0gwoQTOaZOLI-QfSNc
46123
```
47124
48-
### Websocket Connections
125+
Assuming you've set up a todos service, here is full request example you can try out. Be sure to replace `<token>` with a token you've retrieved from your `loginEndpoint`:
126+
127+
```js
128+
// List Accounts (GET http://localhost:3030/api/todos)
129+
jQuery.ajax({
130+
url: 'http://localhost:3030/api/todos',
131+
type: 'GET',
132+
headers: {
133+
"Authorization": "Bearer <token>",
134+
"Accept": "application/json",
135+
},
136+
})
137+
.done(function(data, textStatus, jqXHR) {
138+
console.log("HTTP Request Succeeded: " + jqXHR.status);
139+
console.log(data);
140+
})
141+
.fail(function(jqXHR, textStatus, errorThrown) {
142+
console.log("HTTP Request Failed", arguments);
143+
});
144+
```
145+
146+
### Authenticating Socket.io Connections
147+
49148
In order to authenticate a Websocket connection, you must first obtain a token using an Ajax request to your `loginEndpoint`. You then include that token in the request. The example below is for Socket.io, but the same `query` key can be passed to Primus.
50149
51150
```js
52151
socket = io('', {
53-
// Assuming you've already saved a token to localStorage.
54-
query: 'token=' + localStorage.getItem('featherstoken'),
55-
transports: ['websocket'], // optional, see below
56-
forceNew:true, // optional, see below
152+
// Assuming you've already saved a token to localStorage.
153+
query: 'token=' + localStorage.getItem('featherstoken'),
154+
transports: ['websocket'], // optional, see below
155+
forceNew:true, // optional, see below
57156
});
58157
```
59158
60-
In the above example, the `transports` key is only needed if you for some reason need to force the browser to only use websockets. The `forceNew` key is only needed if you have previously connected an *unauthenticated* Websocket connection and you now want to start an authenticated request.
159+
In the above example, the `transports` key is only needed if you, for some reason, need to force the browser to only use websockets. The `forceNew` key is only needed if you have previously connected an *unauthenticated* Websocket connection and you now want to start an *authenticated* request.
160+
61161
62162
## Options
63163

0 commit comments

Comments
 (0)