angel_auth_oauth2 2.0.0+1

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 66

auth_oauth2 #

Pub

package:angel_auth strategy for OAuth2 login, i.e. Facebook or Github.

Usage #

First, create an options object:

configureServer(Angel app) async {
  // Load from a Map, i.e. app config:
  var opts = new AngelOAuth2Options.fromJson(map);
  
  // Create in-place:
  var opts = const AngelAuthOAuth2Options(
      callback: '<callback-url>',
      key: '<client-id>',
      secret: '<client-secret>',
      authorizationEndpoint: '<authorization-endpoint>',
      tokenEndpoint: '<access-token-endpoint>');
}

After getting authenticated against the remote server, we need to be able to identify users within our own application. Use an OAuth2Verifier to associate remote users with local users.

/// You might use a pure function to create a verifier that queries a
/// given service.
OAuth2Verifier oauth2verifier(Service userService) {
  return (oauth2.Client client) async {
     var response = await client.get('https://api.github.com/user');
     var ghUser = JSON.decode(response.body);
     var id = ghUser['id'];
 
     Iterable<Map> matchingUsers = await userService.index({
       'query': {'githubId': id}
     });
 
     if (matchingUsers.isNotEmpty) {
       // Return the corresponding user, if it exists
       return User.parse(matchingUsers.firstWhere((u) => u['githubId'] == id));
     } else {
       // Otherwise,create a user
       return await userService.create({'githubId': id}).then(User.parse);
     }
   };
}

Now, initialize an OAuth2Strategy, using the options and verifier. You'll also need to provide a name for this instance of the strategy. Consider using the name of the remote authentication provider (ex. facebook).

configureServer(Angel app) {
  // ...
  var oauthStrategy =
    new OAuth2Strategy('github', OAUTH2_CONFIG, oauth2Verifier(app.service('users')));
}

Lastly, connect it to an AngelAuth instance, and wire it up to an Angel server. Set up two routes:

  1. Redirect users to the external provider
  2. Acts as a callback and handles an access code

In the case of the callback route, you may want to display an HTML page that closes a popup window. In this case, use confirmPopupAuthentication, which is bundled with package:angel_auth, as a callback function:

configureServer(Angel app) async {
  // ...
  var auth = new AngelAuth();
  auth.strategies['github'] = oauth2Strategy;
  
  // Redirect
  app.get('/auth/github', auth.authenticate('github'));
  
  // Callback
  app.get('/auth/github/callback', auth.authenticate(
    'github',
    new AngelAuthOptions(callback: confirmPopupAuthentication())
  ));
  
  // Connect the plug-in!!!
  await app.configure(auth);
}

Custom Scope Delimiter #

This package should work out-of-the-box for most OAuth2 providers, such as Github or Dropbox. However, if your OAuth2 scopes are separated by a delimiter other than the default (' '), you can add it in the AngelOAuth2Options constructor:

configureServer(Angel app) async {
  var opts = const AngelOAuth2Options(
    // ...
    delimiter: ','
  );
}

Handling non-JSON responses #

Many OAuth2 providers do not follow the specification, and do not return application/json responses.

You can add a getParameters callback to parse the contents of any arbitrary response:

var opts = const AngelOAuth2Options(
    // ...
    getParameters: (contentType, body) {
      if (contentType.type == 'application') {
        if (contentType.subtype == 'x-www-form-urlencoded')
          return Uri.splitQueryString(body);
        else if (contentType.subtype == 'json') return JSON.decode(body);
      }

      throw new FormatException('Invalid content-type $contentType; expected application/x-www-form-urlencoded or application/json.');
    }
);

2.0.0+1 #

  • Meta update to improve Pub score.

2.0.0 #

  • Angel 2 + Dart 2 updates.

1.0.2 #

Added getParameters to AngelOAuth2Options.

example/main.dart

import 'dart:convert';
import 'dart:io';
import 'package:angel_auth/angel_auth.dart';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_auth_oauth2/angel_auth_oauth2.dart';
import 'package:logging/logging.dart';
import 'package:oauth2/oauth2.dart' as oauth2;

final AngelAuthOAuth2Options oAuth2Config = new AngelAuthOAuth2Options(
    callback: 'http://localhost:3000/auth/github/callback',
    key: '6caeaf5d4c04936ec34f',
    secret: '178360518cf9de4802e2346a4b6ebec525dc4427',
    authorizationEndpoint: 'http://github.com/login/oauth/authorize',
    tokenEndpoint: 'https://github.com/login/oauth/access_token',
    getParameters: (contentType, body) {
      if (contentType.type == 'application') {
        if (contentType.subtype == 'x-www-form-urlencoded')
          return Uri.splitQueryString(body);
        else if (contentType.subtype == 'json')
          return (json.decode(body) as Map).cast<String, String>();
      }

      throw new FormatException(
          'Invalid content-type $contentType; expected application/x-www-form-urlencoded or application/json.');
    });

main() async {
  var app = new Angel();
  app.use('/users', new MapService());

  var auth =
      new AngelAuth<User>(jwtKey: 'oauth2 example secret', allowCookie: false);

  auth.deserializer =
      (id) => app.service('users').read(id).then((u) => User.parse(u as Map));

  auth.serializer = (User user) async => user.id;

  auth.strategies['github'] = new OAuth2Strategy(
    oAuth2Config,
    (oauth2.Client client) async {
      var response = await client.get('https://api.github.com/user');
      var ghUser = json.decode(response.body);
      var id = ghUser['id'];

      Iterable<Map> matchingUsers = await app.service('users').index({
        'query': {'githubId': id}
      });

      if (matchingUsers.isNotEmpty) {
        // Return the corresponding user, if it exists
        return User.parse(matchingUsers.firstWhere((u) => u['githubId'] == id));
      } else {
        // Otherwise,create a user
        return await app
            .service('users')
            .create({'githubId': id}).then((u) => User.parse(u as Map));
      }
    },
  );

  app.get('/auth/github', auth.authenticate('github'));
  app.get(
      '/auth/github/callback',
      auth.authenticate('github',
          new AngelAuthOptions(callback: (req, res, jwt) async {
        // In real-life, you might include a pop-up callback script.
        //
        // Use `confirmPopupAuthentication`, which is bundled with
        // `package:angel_auth`.
        res.write('Your JWT: $jwt');
      })));

  await app.configure(auth.configureServer);

  app.logger = new Logger('angel')..onRecord.listen(print);

  var http = new AngelHttp(app);
  var server = await http.startServer(InternetAddress.loopbackIPv4, 3000);
  var url = 'http://${server.address.address}:${server.port}';
  print('Listening on $url');
  print('View user listing: $url/users');
  print('Sign in via Github: $url/auth/github');
}

class User extends Model {
  @override
  String id;
  int githubId;

  User({this.id, this.githubId});

  static User parse(Map map) =>
      new User(id: map['id'] as String, githubId: map['github_id'] as int);

  Map<String, dynamic> toJson() => {'id': id, 'github_id': githubId};
}

Use this package as a library

1. Depend on it

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


dependencies:
  angel_auth_oauth2: ^2.0.0+1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

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

3. Import it

Now in your Dart code, you can use:


import 'package:angel_auth_oauth2/angel_auth_oauth2.dart';
  
Version Uploaded Documentation Archive
2.1.0 Jan 6, 2019 Go to the documentation of angel_auth_oauth2 2.1.0 Download angel_auth_oauth2 2.1.0 archive
2.0.0+1 Sep 12, 2018 Go to the documentation of angel_auth_oauth2 2.0.0+1 Download angel_auth_oauth2 2.0.0+1 archive
2.0.0 Sep 12, 2018 Go to the documentation of angel_auth_oauth2 2.0.0 Download angel_auth_oauth2 2.0.0 archive
1.0.2 Mar 30, 2018 Go to the documentation of angel_auth_oauth2 1.0.2 Download angel_auth_oauth2 1.0.2 archive
1.0.1 Jun 3, 2017 Go to the documentation of angel_auth_oauth2 1.0.1 Download angel_auth_oauth2 1.0.1 archive
1.0.0 Feb 23, 2017 Go to the documentation of angel_auth_oauth2 1.0.0 Download angel_auth_oauth2 1.0.0 archive
0.0.0 Jan 12, 2017 Go to the documentation of angel_auth_oauth2 0.0.0 Download angel_auth_oauth2 0.0.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
34
Health:
Code health derived from static analysis. [more]
98
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
66
Learn more about scoring.

We analyzed this package on May 23, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.3.1
  • pana: 0.12.16

Platforms

Detected platforms: Flutter, other

Primary library: package:angel_auth_oauth2/angel_auth_oauth2.dart with components: io.

Health suggestions

Fix lib/angel_auth_oauth2.dart. (-2.48 points)

Analysis of lib/angel_auth_oauth2.dart reported 5 hints:

line 52 col 21: Use = to separate a named parameter from its default value.

line 53 col 18: Use = to separate a named parameter from its default value.

line 88 col 7: DO use curly braces for all flow control structures.

line 91 col 7: DO use curly braces for all flow control structures.

line 109 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev <3.0.0
angel_auth ^2.0.0 2.1.5+1
angel_framework ^2.0.0-alpha 2.0.1
angel_validate ^2.0.0-alpha 2.0.1
http_parser ^3.0.0 3.1.3
oauth2 ^1.0.0 1.2.3
Transitive dependencies
angel_container 1.0.4
angel_http_exception 1.1.0
angel_model 1.0.3
angel_route 3.0.6
async 2.2.0
charcode 1.1.2
code_buffer 1.0.1
collection 1.14.11
combinator 1.1.0
convert 2.1.1
crypto 2.0.6
dart2_constant 1.0.2+dart2
file 5.0.8
http 0.12.0+2
http2 1.0.0
http_server 0.9.8+1
intl 0.15.8
matcher 0.12.5
merge_map 1.0.2
meta 1.1.7
mime 0.9.6+2
mock_request 1.0.5
path 1.6.2
pedantic 1.7.0
quiver 2.0.3
quiver_hashcode 2.0.0
source_span 1.5.5
stack_trace 1.9.3
string_scanner 1.0.4
term_glyph 1.1.0
tuple 1.0.2
typed_data 1.1.6
uuid 2.0.1
Dev dependencies
logging ^0.11.0 0.11.3+2