jaguar_auth 0.12.0

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:

  1. Basic auth
  2. Form auth
  3. JSON auth

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:

  1. fetchModelByAuthenticationId
  2. fetchModelByAuthorizationId
  3. authenticate

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:

  1. MongoDB based
  2. 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

Changelog

0.12.0

  • Renames methods on AuthModelManager to be shorter
  • Made methods on AuthModelManager FutureOr

0.11.3

  • Moved to jaguar_serializer 0.5.x

0.11.0

  • Uses Session from jaguar package

0.0.1

  • Initial version, created by Stagehand

1. Depend on it

Add this to your package's pubspec.yaml file:

dependencies:
  jaguar_auth: "^0.12.0"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

Alternatively, your editor might support pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:jaguar_auth/jaguar_auth.dart';

Platforms

Server

About

Authentication interceptors and helper functions for Jaguar

Author

Ravi Teja Gudapati
Kevin Segaud

Homepage

github.com/Jaguar-dart/jaguar_auth

Documentation

www.dartdocs.org/documentation/jaguar_auth/0.12.0/

Uploader

segaud.kevin@gmail.com
tejainece@gmail.com

License

BSD (LICENSE)

Published

Nov 5, 2017