1.0.3
This commit is contained in:
parent
e4bcd3cb47
commit
54fb98948a
5 changed files with 40 additions and 24 deletions
|
@ -12,7 +12,7 @@
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="Dart SDK" level="application" />
|
|
||||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||||
|
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -1,6 +1,6 @@
|
||||||
# angel_auth
|
# angel_auth
|
||||||
|
|
||||||
[![version 1.0.2](https://img.shields.io/badge/version-1.0.2-brightgreen.svg)](https://pub.dartlang.org/packages/angel_auth)
|
[![version 1.0.3](https://img.shields.io/badge/version-1.0.3-brightgreen.svg)](https://pub.dartlang.org/packages/angel_auth)
|
||||||
![build status](https://travis-ci.org/angel-dart/auth.svg?branch=master)
|
![build status](https://travis-ci.org/angel-dart/auth.svg?branch=master)
|
||||||
|
|
||||||
A complete authentication plugin for Angel. Inspired by Passport.
|
A complete authentication plugin for Angel. Inspired by Passport.
|
||||||
|
|
|
@ -2,8 +2,29 @@ import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:angel_framework/angel_framework.dart';
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
|
|
||||||
|
/// Restricts access to a resource via authentication. Constant instance.
|
||||||
|
const RequestMiddleware requireAuth = const RequireAuthorizationMiddleware();
|
||||||
|
|
||||||
|
/// Forces Basic authentication over the requested resource, with the given [realm] name, if no JWT is present.
|
||||||
|
///
|
||||||
|
/// [realm] defaults to `'angel_auth'`.
|
||||||
|
RequestHandler forceBasicAuth({String realm}) {
|
||||||
|
return (RequestContext req, ResponseContext res) async {
|
||||||
|
if (req.properties.containsKey('user')) return true;
|
||||||
|
|
||||||
|
res
|
||||||
|
..statusCode = HttpStatus.UNAUTHORIZED
|
||||||
|
..headers[HttpHeaders.WWW_AUTHENTICATE] =
|
||||||
|
'Basic realm="${realm ?? 'angel_auth'}"'
|
||||||
|
..end();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Restricts access to a resource via authentication.
|
/// Restricts access to a resource via authentication.
|
||||||
class RequireAuthorizationMiddleware extends AngelMiddleware {
|
class RequireAuthorizationMiddleware implements AngelMiddleware {
|
||||||
|
const RequireAuthorizationMiddleware();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> call(RequestContext req, ResponseContext res,
|
Future<bool> call(RequestContext req, ResponseContext res,
|
||||||
{bool throwError: true}) async {
|
{bool throwError: true}) async {
|
||||||
|
|
|
@ -14,8 +14,6 @@ class AngelAuth extends AngelPlugin {
|
||||||
num _jwtLifeSpan;
|
num _jwtLifeSpan;
|
||||||
Math.Random _random = new Math.Random.secure();
|
Math.Random _random = new Math.Random.secure();
|
||||||
final RegExp _rgxBearer = new RegExp(r"^Bearer");
|
final RegExp _rgxBearer = new RegExp(r"^Bearer");
|
||||||
RequireAuthorizationMiddleware _requireAuth =
|
|
||||||
new RequireAuthorizationMiddleware();
|
|
||||||
final bool allowCookie;
|
final bool allowCookie;
|
||||||
final bool allowTokenInQuery;
|
final bool allowTokenInQuery;
|
||||||
String middlewareName;
|
String middlewareName;
|
||||||
|
@ -59,13 +57,19 @@ class AngelAuth extends AngelPlugin {
|
||||||
if (runtimeType != AngelAuth) app.container.singleton(this, as: AngelAuth);
|
if (runtimeType != AngelAuth) app.container.singleton(this, as: AngelAuth);
|
||||||
|
|
||||||
app.before.add(decodeJwt);
|
app.before.add(decodeJwt);
|
||||||
app.registerMiddleware(middlewareName, _requireAuth);
|
app.registerMiddleware(middlewareName, requireAuth);
|
||||||
|
|
||||||
if (reviveTokenEndpoint != null) {
|
if (reviveTokenEndpoint != null) {
|
||||||
app.post(reviveTokenEndpoint, reviveJwt);
|
app.post(reviveTokenEndpoint, reviveJwt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _apply(RequestContext req, AuthToken token, user) {
|
||||||
|
req
|
||||||
|
..inject(AuthToken, req.properties['token'] = token)
|
||||||
|
..inject(user.runtimeType, req.properties["user"] = user);
|
||||||
|
}
|
||||||
|
|
||||||
decodeJwt(RequestContext req, ResponseContext res) async {
|
decodeJwt(RequestContext req, ResponseContext res) async {
|
||||||
if (req.method == "POST" && req.path == reviveTokenEndpoint) {
|
if (req.method == "POST" && req.path == reviveTokenEndpoint) {
|
||||||
// Shouldn't block invalid JWT if we are reviving it
|
// Shouldn't block invalid JWT if we are reviving it
|
||||||
|
@ -119,10 +123,7 @@ class AngelAuth extends AngelPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
final user = await deserializer(token.userId);
|
final user = await deserializer(token.userId);
|
||||||
|
_apply(req, token, user);
|
||||||
req
|
|
||||||
..inject(AuthToken, req.properties['token'] = token)
|
|
||||||
..inject(user.runtimeType, req.properties["user"] = user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -243,9 +244,7 @@ class AngelAuth extends AngelPlugin {
|
||||||
if (r != null) return r;
|
if (r != null) return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
req
|
_apply(req, token, result);
|
||||||
..inject(AuthToken, req.properties['token'] = token)
|
|
||||||
..inject(result.runtimeType, req.properties["user"] = result);
|
|
||||||
|
|
||||||
if (allowCookie) res.cookies.add(new Cookie("token", jwt));
|
if (allowCookie) res.cookies.add(new Cookie("token", jwt));
|
||||||
|
|
||||||
|
@ -254,13 +253,15 @@ class AngelAuth extends AngelPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options?.successRedirect?.isNotEmpty == true) {
|
if (options?.successRedirect?.isNotEmpty == true) {
|
||||||
return res.redirect(options.successRedirect, code: HttpStatus.OK);
|
res.redirect(options.successRedirect, code: HttpStatus.OK);
|
||||||
|
return false;
|
||||||
} else if (options?.canRespondWithJson != false &&
|
} else if (options?.canRespondWithJson != false &&
|
||||||
req.headers.value("accept") != null &&
|
req.headers.value("accept") != null &&
|
||||||
(req.headers.value("accept").contains("application/json") ||
|
(req.headers.value("accept").contains("application/json") ||
|
||||||
req.headers.value("accept").contains("*/*") ||
|
req.headers.value("accept").contains("*/*") ||
|
||||||
req.headers.value("accept").contains("application/*"))) {
|
req.headers.value("accept").contains("application/*"))) {
|
||||||
return {"data": result, "token": jwt};
|
var user = await deserializer(await serializer(result));
|
||||||
|
return {"data": user, "token": jwt};
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -277,10 +278,7 @@ class AngelAuth extends AngelPlugin {
|
||||||
/// Log a user in on-demand.
|
/// Log a user in on-demand.
|
||||||
Future login(AuthToken token, RequestContext req, ResponseContext res) async {
|
Future login(AuthToken token, RequestContext req, ResponseContext res) async {
|
||||||
var user = await deserializer(token.userId);
|
var user = await deserializer(token.userId);
|
||||||
|
_apply(req, token, user);
|
||||||
req
|
|
||||||
..inject(AuthToken, req.properties['token'] = token)
|
|
||||||
..inject(user.runtimeType, req.properties["user"] = user);
|
|
||||||
|
|
||||||
if (allowCookie)
|
if (allowCookie)
|
||||||
res.cookies.add(new Cookie('token', token.serialize(_hs256)));
|
res.cookies.add(new Cookie('token', token.serialize(_hs256)));
|
||||||
|
@ -291,10 +289,7 @@ class AngelAuth extends AngelPlugin {
|
||||||
var user = await deserializer(userId);
|
var user = await deserializer(userId);
|
||||||
var token = new AuthToken(
|
var token = new AuthToken(
|
||||||
userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip);
|
userId: userId, lifeSpan: _jwtLifeSpan, ipAddress: req.ip);
|
||||||
|
_apply(req, token, user);
|
||||||
req
|
|
||||||
..inject(AuthToken, req.properties['token'] = token)
|
|
||||||
..inject(user.runtimeType, req.properties["user"] = user);
|
|
||||||
|
|
||||||
if (allowCookie)
|
if (allowCookie)
|
||||||
res.cookies.add(new Cookie('token', token.serialize(_hs256)));
|
res.cookies.add(new Cookie('token', token.serialize(_hs256)));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: angel_auth
|
name: angel_auth
|
||||||
description: A complete authentication plugin for Angel.
|
description: A complete authentication plugin for Angel.
|
||||||
version: 1.0.2
|
version: 1.0.3
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_auth
|
homepage: https://github.com/angel-dart/angel_auth
|
||||||
environment:
|
environment:
|
||||||
|
|
Loading…
Reference in a new issue