Only encode the signature
This commit is contained in:
parent
df2a6c7096
commit
c045da3e03
2 changed files with 68 additions and 7 deletions
59
example/cookie_signer.dart
Normal file
59
example/cookie_signer.dart
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
|
import 'package:angel_framework/http.dart';
|
||||||
|
import 'package:angel_security/angel_security.dart';
|
||||||
|
import 'package:http_parser/http_parser.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:pretty_logging/pretty_logging.dart';
|
||||||
|
|
||||||
|
main() async {
|
||||||
|
// Logging boilerplate.
|
||||||
|
Logger.root.onRecord.listen(prettyLog);
|
||||||
|
|
||||||
|
// Create an app, and HTTP driver.
|
||||||
|
var app = Angel(logger: Logger('cookie_signer')), http = AngelHttp(app);
|
||||||
|
|
||||||
|
// Create a cookie signer. Uses an SHA256 Hmac by default.
|
||||||
|
var signer = CookieSigner.fromStringKey(
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ab');
|
||||||
|
|
||||||
|
// When a user visits /getid, give them a (signed) uniqid cookie.
|
||||||
|
// When they visit /cookies, print their verified cookies.
|
||||||
|
var rnd = Random.secure();
|
||||||
|
|
||||||
|
// Endpoint to give a signed cookie.
|
||||||
|
app.get('/getid', (req, res) {
|
||||||
|
// Write the uniqid cookie.
|
||||||
|
var uniqid = rnd.nextInt(65536);
|
||||||
|
signer.writeCookies(res, [
|
||||||
|
Cookie('uniqid', uniqid.toString()),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Send a response.
|
||||||
|
res.write('uniqid=$uniqid');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Endpoint to dump all verified cookies.
|
||||||
|
//
|
||||||
|
// The [onInvalidCookie] callback is optional, but
|
||||||
|
// here we will use it to log invalid cookies.
|
||||||
|
app.get('/cookies', (req, res) {
|
||||||
|
var verifiedCookies = signer.readCookies(req, onInvalidCookie: (cookie) {
|
||||||
|
app.logger.warning('Invalid cookie: $cookie');
|
||||||
|
});
|
||||||
|
res.writeln('${verifiedCookies.length} verified cookie(s)');
|
||||||
|
res.writeln('${req.cookies.length} total unverified cookie(s)');
|
||||||
|
for (var cookie in verifiedCookies) {
|
||||||
|
res.writeln('${cookie.name}=${cookie.value}');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 404 otherwise.
|
||||||
|
app.fallback((req, res) => throw AngelHttpException.notFound(
|
||||||
|
message: 'The only valid endpoints are /getid and /cookies.'));
|
||||||
|
|
||||||
|
// Start the server.
|
||||||
|
await http.startServer('127.0.0.1', 3000);
|
||||||
|
print('Cookie signer example listening at ${http.uri}');
|
||||||
|
}
|
|
@ -90,12 +90,13 @@ class CookieSigner {
|
||||||
/// Returns a new cookie, replacing the value of an input
|
/// Returns a new cookie, replacing the value of an input
|
||||||
/// [cookie] with one that is signed with the [hmac].
|
/// [cookie] with one that is signed with the [hmac].
|
||||||
///
|
///
|
||||||
/// The signature is:
|
/// The new value is:
|
||||||
/// `base64Url(cookie.value) + "." + base64Url(sig)`
|
/// `cookie.value + "." + base64Url(sig)`
|
||||||
///
|
///
|
||||||
/// Where `sig` is the cookie's value, signed with the [hmac].
|
/// Where `sig` is the cookie's value, signed with the [hmac].
|
||||||
Cookie createSignedCookie(Cookie cookie) {
|
Cookie createSignedCookie(Cookie cookie) {
|
||||||
return cookieWithNewValue(cookie, computeCookieSignature(cookie.value));
|
return cookieWithNewValue(
|
||||||
|
cookie, cookie.value + '.' + computeCookieSignature(cookie.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [Cookie] that is the same as the input
|
/// Returns a new [Cookie] that is the same as the input
|
||||||
|
@ -110,13 +111,14 @@ class CookieSigner {
|
||||||
..secure = cookie.secure;
|
..secure = cookie.secure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the signature of a [cookieValue], either for
|
/// Computes the *signature* of a [cookieValue], either for
|
||||||
/// signing an outgoing cookie, or verifying an incoming cookie.
|
/// signing an outgoing cookie, or verifying an incoming cookie.
|
||||||
String computeCookieSignature(String cookieValue) {
|
String computeCookieSignature(String cookieValue) {
|
||||||
// base64Url(cookie) + "." + base64Url(sig)
|
// base64Url(cookie) + "." + base64Url(sig)
|
||||||
var encodedCookie = base64Url.encode(cookieValue.codeUnits);
|
// var encodedCookie = base64Url.encode(cookieValue.codeUnits);
|
||||||
var sigBytes = hmac.convert(cookieValue.codeUnits).bytes;
|
var sigBytes = hmac.convert(cookieValue.codeUnits).bytes;
|
||||||
var sig = base64Url.encode(sigBytes);
|
return base64Url.encode(sigBytes);
|
||||||
return encodedCookie + '.' + sig;
|
// var sig = base64Url.encode(sigBytes);
|
||||||
|
// return encodedCookie + '.' + sig;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue