Let’s get started. The first part of authentication setup is setting up a serializer and deserializer that can be used to read and store a user in a JWT.

main() {

var app = new Angel();

var auth = new AngelAuth(jwtKey: 'my jwt secret', allowCookie: false); // The JWT's userId will be the result of this function

auth.serializer = (User user) async => user.id; // The result of this is added to req.properties on each request.

// Ex. auth.deserializer = (String id) async => ...

//

// In Angel applications, you can easily find a user using a service.

auth.deserializer = app.service('users').read; // Plug-in must be configured, or else users will never be deserialized

// from JWT's.

await app.configure(auth);

}

Without adding strategies, users can never authenticate into our applications. The auth package includes just one: local authentication, which logs users in based on a username and password. This is more or less the same as passport-local . Local authentication requires a Verifier function that retrieves a user based on a username and password. Failed log-in attempts should return null .

main() {

// ...

var verifierFn = verifier(app.service('users'));

var strategy = new LocalAuthStrategy(verifier: verifierFn);

auth.strategies.add(strategy);

} verifier(Service Users) {

return (String username, String password) async {

List<User> users = await Users.index({'username': username}); if (users.isNotEmpty) {

var hash = hashPassword(password);

return users.firstWhere((user) => user.password == hash,

orElse: () => null);

}

};

}

Lastly, we need to add routes that call our auth setup. The AngelAuth exposes a function called authenticate that runs a given strategy, and serializes the authenticated user to a JWT. If authentication fails, a new AngelHttpException.notAuthenticated is thrown. If we left allowCookie as true , which is the default, then it would also set a cookie named token . In practice, however, the cookie turns out to be unnecessary.

main() {

// ...

app.post('/login', auth.authenticate('local'));

}