Added getParameters
This commit is contained in:
parent
3944a3f482
commit
ed3cb579ae
8 changed files with 73 additions and 43 deletions
|
@ -5,8 +5,6 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/example/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/packages" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Github Auth Server" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true">
|
||||
<option name="filePath" value="$PROJECT_DIR$/example/github.dart" />
|
||||
<option name="filePath" value="$PROJECT_DIR$/example/main.dart" />
|
||||
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||
<method />
|
||||
</configuration>
|
||||
|
|
2
CHANGELOG.md
Normal file
2
CHANGELOG.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# 1.0.2
|
||||
Added `getParameters` to `AngelOAuth2Options`.
|
28
README.md
28
README.md
|
@ -1,6 +1,6 @@
|
|||
# auth_oauth2
|
||||
|
||||
[![version 1.0.1](https://img.shields.io/badge/pub-1.0.1-brightgreen.svg)](https://pub.dartlang.org/packages/angel_auth_oauth2)
|
||||
[![Pub](https://img.shields.io/pub/v/angel_auth_oauth2.svg)](https://pub.dartlang.org/packages/angel_auth_oauth2)
|
||||
|
||||
`package:angel_auth` strategy for OAuth2 login, i.e. Facebook or Github.
|
||||
|
||||
|
@ -13,7 +13,7 @@ configureServer(Angel app) async {
|
|||
var opts = new AngelOAuth2Options.fromJson(map);
|
||||
|
||||
// Create in-place:
|
||||
const AngelAuthOAuth2Options OAUTH2_CONFIG = const AngelAuthOAuth2Options(
|
||||
var opts = const AngelAuthOAuth2Options(
|
||||
callback: '<callback-url>',
|
||||
key: '<client-id>',
|
||||
secret: '<client-secret>',
|
||||
|
@ -98,9 +98,31 @@ you can add it in the `AngelOAuth2Options` constructor:
|
|||
|
||||
```dart
|
||||
configureServer(Angel app) async {
|
||||
const AngelOAuth2Options OPTS = const AngelOAuth2Options(
|
||||
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:
|
||||
|
||||
```dart
|
||||
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.');
|
||||
}
|
||||
);
|
||||
```
|
|
@ -1,31 +1,43 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:angel_auth/angel_auth.dart';
|
||||
import 'package:angel_diagnostics/angel_diagnostics.dart';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/common.dart';
|
||||
import 'package:angel_auth_oauth2/angel_auth_oauth2.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:oauth2/oauth2.dart' as oauth2;
|
||||
|
||||
const AngelAuthOAuth2Options OAUTH2_CONFIG = const AngelAuthOAuth2Options(
|
||||
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');
|
||||
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);
|
||||
}
|
||||
|
||||
throw new FormatException('Invalid content-type $contentType; expected application/x-www-form-urlencoded or application/json.');
|
||||
});
|
||||
|
||||
main() async {
|
||||
var app = new Angel();
|
||||
app.lazyParseBodies = true;
|
||||
app.use('/users', new MapService());
|
||||
|
||||
var auth = new AngelAuth(jwtKey: 'oauth2 example secret', allowCookie: false);
|
||||
var auth =
|
||||
new AngelAuth<User>(jwtKey: 'oauth2 example secret', allowCookie: false);
|
||||
|
||||
auth.deserializer =
|
||||
(id) => app.service('users').read(id).then((u) => User.parse(u));
|
||||
|
||||
auth.deserializer = app.service('users').read;
|
||||
auth.serializer = (User user) async => user.id;
|
||||
|
||||
auth.strategies.add(
|
||||
new OAuth2Strategy('github', OAUTH2_CONFIG, (oauth2.Client client) async {
|
||||
new OAuth2Strategy('github', 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'];
|
||||
|
@ -41,7 +53,7 @@ main() async {
|
|||
// Otherwise,create a user
|
||||
return await app
|
||||
.service('users')
|
||||
.create({'githubId': id}).then(User.parse);
|
||||
.create({'githubId': id}).then((u) => User.parse(u));
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -57,10 +69,12 @@ main() async {
|
|||
res.write('Your JWT: $jwt');
|
||||
})));
|
||||
|
||||
await app.configure(auth);
|
||||
await app.configure(logRequests());
|
||||
await app.configure(auth.configureServer);
|
||||
|
||||
var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 3000);
|
||||
app.logger = new Logger('angel')..onRecord.listen(print);
|
||||
|
||||
var http = new AngelHttp(app);
|
||||
var server = await http.startServer(InternetAddress.LOOPBACK_IP_V4, 3000);
|
||||
var url = 'http://${server.address.address}:${server.port}';
|
||||
print('Listening on $url');
|
||||
print('View user listing: $url/users');
|
|
@ -2,21 +2,18 @@ library angel_auth_oauth2;
|
|||
|
||||
import 'dart:async';
|
||||
import 'package:angel_auth/angel_auth.dart';
|
||||
import 'package:angel_framework/src/http/response_context.dart';
|
||||
import 'package:angel_framework/src/http/request_context.dart';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_validate/angel_validate.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:oauth2/oauth2.dart' as oauth2;
|
||||
|
||||
/// Loads a user profile via OAuth2.
|
||||
typedef Future OAuth2Verifier(oauth2.Client client);
|
||||
|
||||
final Validator OAUTH2_OPTIONS_SCHEMA = new Validator({
|
||||
'key*': isString,
|
||||
'secret*': isString,
|
||||
'authorizationEndpoint*': isString,
|
||||
'tokenEndpoint*': isString,
|
||||
'authorizationEndpoint*': anyOf(isString, const isInstanceOf<Uri>()),
|
||||
'tokenEndpoint*': anyOf(isString, const isInstanceOf<Uri>()),
|
||||
'callback*': isString,
|
||||
'scopes': new isInstanceOf<Iterable<String>>()
|
||||
'scopes': const isInstanceOf<Iterable<String>>()
|
||||
}, defaultValues: {
|
||||
'scopes': <String>[]
|
||||
}, customErrorMessages: {
|
||||
|
@ -32,10 +29,10 @@ class AngelAuthOAuth2Options {
|
|||
final String secret;
|
||||
|
||||
/// The remote endpoint that prompts external users for authentication credentials.
|
||||
final String authorizationEndpoint;
|
||||
final authorizationEndpoint;
|
||||
|
||||
/// The remote endpoint that exchanges auth codes for access tokens.
|
||||
final String tokenEndpoint;
|
||||
final tokenEndpoint;
|
||||
|
||||
/// The callback URL that the OAuth2 server should redirect authenticated users to.
|
||||
final String callback;
|
||||
|
@ -44,6 +41,8 @@ class AngelAuthOAuth2Options {
|
|||
final String delimiter;
|
||||
final Iterable<String> scopes;
|
||||
|
||||
final Map<String, String> Function(MediaType, String) getParameters;
|
||||
|
||||
const AngelAuthOAuth2Options(
|
||||
{this.key,
|
||||
this.secret,
|
||||
|
@ -51,7 +50,8 @@ class AngelAuthOAuth2Options {
|
|||
this.tokenEndpoint,
|
||||
this.callback,
|
||||
this.delimiter: ' ',
|
||||
this.scopes: const []});
|
||||
this.scopes: const [],
|
||||
this.getParameters});
|
||||
|
||||
factory AngelAuthOAuth2Options.fromJson(Map json) =>
|
||||
new AngelAuthOAuth2Options(
|
||||
|
@ -62,7 +62,7 @@ class AngelAuthOAuth2Options {
|
|||
callback: json['callback'],
|
||||
scopes: json['scopes'] ?? <String>[]);
|
||||
|
||||
Map<String, String> toJson() {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'key': key,
|
||||
'secret': secret,
|
||||
|
@ -74,19 +74,14 @@ class AngelAuthOAuth2Options {
|
|||
}
|
||||
}
|
||||
|
||||
class OAuth2Strategy implements AuthStrategy {
|
||||
String _name;
|
||||
class OAuth2Strategy<T> implements AuthStrategy {
|
||||
final FutureOr<T> Function(oauth2.Client) verifier;
|
||||
String name;
|
||||
|
||||
AngelAuthOAuth2Options _options;
|
||||
final OAuth2Verifier verifier;
|
||||
|
||||
@override
|
||||
String get name => _name;
|
||||
|
||||
@override
|
||||
set name(String value) => _name = name;
|
||||
|
||||
/// [options] can be either a `Map` or an instance of [AngelAuthOAuth2Options].
|
||||
OAuth2Strategy(this._name, options, this.verifier) {
|
||||
OAuth2Strategy(this.name, options, this.verifier) {
|
||||
if (options is AngelAuthOAuth2Options)
|
||||
_options = options;
|
||||
else if (options is Map)
|
||||
|
@ -102,7 +97,8 @@ class OAuth2Strategy implements AuthStrategy {
|
|||
Uri.parse(_options.authorizationEndpoint),
|
||||
Uri.parse(_options.tokenEndpoint),
|
||||
secret: _options.secret,
|
||||
delimiter: _options.delimiter ?? ' ');
|
||||
delimiter: _options.delimiter ?? ' ',
|
||||
getParameters: _options.getParameters);
|
||||
|
||||
@override
|
||||
Future authenticate(RequestContext req, ResponseContext res,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: angel_auth_oauth2
|
||||
description: angel_auth strategy for OAuth2 login, i.e. Facebook.
|
||||
version: 1.0.1
|
||||
version: 1.0.2
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
environment:
|
||||
sdk: ">=1.19.0"
|
||||
|
@ -8,6 +8,4 @@ homepage: https://github.com/angel-dart/auth_oauth2.git
|
|||
dependencies:
|
||||
angel_auth: ^1.0.0-dev
|
||||
angel_validate: ^1.0.0-beta
|
||||
oauth2: ^1.0.0
|
||||
dev_dependencies:
|
||||
angel_diagnostics: ^1.0.0-dev
|
||||
oauth2: ^1.0.0
|
Loading…
Reference in a new issue