jaguar_auth 0.12.0 jaguar_auth: ^0.12.0 copied to clipboard
Authentication interceptors and helper functions for Jaguar
jaguar_auth #
Authentication interceptors and helper functions for Jaguar. This package builds on
Session
infrastructure provided by jaguar
.
This package provides three types of authentication:
And an Authorizer
User model #
AuthorizationUser
is the base class user models must implement to work with authenticators,
Authorizer
and AuthModelManager
.
AuthorizationUser
demands that the model implements a getter named authorizationId
that uniquely identifies the model.
Typically, email, username or user id is used as authorizationId
to uniquely identify user models.
Example #
The following user model User
uses user id as authorizationId
. Notice that User
implements
AuthorizationUser
interface.
class User implements AuthorizationUser {
String id;
String username;
String password;
User(this.id, this.username, this.password);
String get authorizationId => id;
}
Model manager #
AuthModelManager
is used by authenticators and authorizer to fetch and authenticate the user model.
AuthModelManager
decouples the user model storage/access from authenticator and authorizer logic.
Programmers can implement AuthModelManager
that store user models in various back-ends.
AuthModelManager
defines three methods:
fetchModelByAuthorizationId
is used by Authorizer
to fetch and authorize
requests. It uses authorizationId
field of AuthorizationUser
to uniquely
identify and fetch user model.
fetchModelByAuthenticationId
is used by authenticate
method to fetch
user model by authentication id. Typically, username, email or phone number is used as authentication id.
authenticate
method authenticates by using authentication id and pass phrase. Internally, authenticate
uses fetchModelByAuthenticationId
to fetch the user model based on authentication id.
It then verifies that the pass phrase matches the one the model has.
Example #
/// Model manager to authenticate against a static list of user models
class WhiteListPasswordChecker implements AuthModelManager<User> {
/// User models to white list
final Map<String, User> models;
/// Password hasher
final Hasher hasher;
const WhiteListPasswordChecker(Map<String, User> models, {Hasher hasher})
: models = models ?? const {},
hasher = hasher ?? const NoHasher();
Future<User> authenticate(
Context ctx, String username, String password) async {
User model = await fetchModelByAuthenticationId(ctx, username);
if (model == null) {
return null;
}
if (!hasher.verify(password, model.password)) {
return null;
}
return model;
}
Future<User> fetchModelByAuthenticationId(
Context ctx, String authName) async =>
models.values
.firstWhere((model) => model.username == authName, orElse: () => null);
Future<User> fetchModelByAuthorizationId(
Context ctx, String sessionId) async {
if (!models.containsKey(sessionId)) {
return null;
}
return models[sessionId];
}
}
final Map<String, User> kUsers = {
'0': new User('0', 'teja', 'word'),
'1': new User('1', 'kleak', 'pass'),
};
final WhiteListPasswordChecker kModelManager =
new WhiteListPasswordChecker(kUsers);
Other packages #
Several implementation of AuthModelManager
exists:
- MongoDB based
- PostgreSQL based
Authorizer #
Authorizer
authorizes the requests. If the authorization fails, it throws 401 http error.
If the authorization succeeds, it returns the user model of the authorized user.
Internally, it uses fetchModelByAuthorizationId
method of AuthModelManager
to fetch user model by authorizationId
.
Example #
@Api(path: '/book')
class StudentRoutes extends Object with JsonRoutes {
JsonRepo get repo => jsonRepo;
@Get()
Response<String> getAllBooks(Context ctx) {
// Authorize. Throws 401 http error, if authorization fails!
Authorizer.authorize(ctx, kModelManager);
return toJson(_books.values);
}
@Get(path: '/:id')
Response<String> getBook(Context ctx) {
// Authorize. Throws 401 http error, if authorization fails!
Authorizer.authorize(ctx, kModelManager);
String id = ctx.pathParams.get('id');
Book book = _books[id];
return toJson(book);
}
}
Basic auth #
BasicAuth performs authentication based on basic authentication.
It expects base64 encoded "username:password" pair in "authorization" header with "Basic" scheme.
Example #
@Api()
class AuthRoutes extends Object with JsonRoutes {
JsonRepo get repo => jsonRepo;
@Post(path: '/login')
@WrapOne(#basicAuth) // Wrap basic authenticator
Response<String> login(Context ctx) {
final User user = ctx.getInput<User>(BasicAuth);
return toJson(user);
}
@Post(path: '/logout')
Future logout(Context ctx) async {
// Clear session data
(await ctx.req.session).clear();
}
BasicAuth basicAuth(Context ctx) => new BasicAuth(kModelManager);
}
Example client #
TODO
Form auth #
An authenticator for standard username password form style login.
It expects a application/x-www-form-urlencoded
encoded body where the
username and password form fields must be called username
and password
respectively.
Example #
@Api()
class AuthRoutes extends Object with JsonRoutes {
JsonRepo get repo => jsonRepo;
@Post(path: '/login')
@WrapOne(#formAuth)
Response<String> login(Context ctx) {
final User user = ctx.getInput<User>(FormAuth);
return toJson(user);
}
@Post(path: '/logout')
Future logout(Context ctx) async {
// Clear session data
(await ctx.req.session).clear();
}
FormAuth formAuth(Context ctx) => new FormAuth(kModelManager);
}
Example client #
TODO
Json auth #
An authenticator for standard username password login using ajax requests.
It expects a application/json
encoded body where the
username and password fields must be called username
and password
respectively.
Example #
@Api()
class AuthRoutes extends Object with JsonRoutes {
JsonRepo get repo => jsonRepo;
@Post(path: '/login')
@WrapOne(#jsonAuth)
Response<String> login(Context ctx) {
final User user = ctx.getInput<User>(JsonAuth);
return toJson(user);
}
@Post(path: '/logout')
Future logout(Context ctx) async {
// Clear session data
(await ctx.req.session).clear();
}
/// The authenticator
JsonAuth jsonAuth(Context ctx) => new JsonAuth(kModelManager);
}
Example client #
TODO