@rcarls/passport-indieauth
v2.0.1
Published
IndieAuth authentication strategy for Passport.
Downloads
5
Maintainers
Readme
An IndieAuth authentication strategy for Passport.
This module exports a Passport Strategy
class to be used by applications that utilize Passport
middleware for authentication. By plugging into Passport, developers can easily integrate IndieAuth
into any Node.js application or framework that supports
Connect-style middleware, including the popular Express.
This strategy only implements the client-side of the IndieAuth protocol, and relies on endpoint discovery to determine how to delegate authentication. A fallback authorization endpoint can be configured, and the strategy defaults to using the canonical indieauth.com.
Breaking changes from v1.x
The verify callback now supplies an access token instead of the requested scope as the second argument. It is given that the requesting app will already know which scope(s) it is requesting, and four arguments to a callback is already one too many.
Install
$ npm install @rcarls/passport-indieauth
Usage
Configure Strategy
The IndieAuth authentication strategy only requires a client id, the domain of the web application, and a redirect URI for authorization flow. The request object can optionally be passed to the verify callback.
require('passport');
require('@rcarls/passport-indieauth');
// ...
passport.use(new IndieAuthStrategy({
clientId: 'https://example-client.com/',
redirectUri: 'https://example-client.com/auth',
passReqToCallback: true,
}, function(req, uid, token, profile, done) {
// The verify callback:
// Verify the returned user credentials are valid
User.findOne({ uid: uid }, function(err, user) {
// and return the existing or newly created user
return done(err, user);
});
});
});
Configuration Options
clientId
{String} - The application's client id. Must be a valid URL that accepts HTTP or HTTPS requests. The convention is to include a trailing slash after the domain name, but is not required. (ex:https://example-client.com/
)redirectUri
{String} - The authorization redirect URI.responseType
{String} - The response type of the auth request. Valid values are'id'
(identification only), or'code'
(identification + authorization) (optional, defaults to 'id')defaultAuthEndpoint
{String} - The fallback authorization service to use if not discovered. (optional, defaults to 'https://indieauth.com/auth')scopeDelimiter
{String} - Delimiter for separating scopes in the request. Defaults to a space.passReqToCallback
{Boolean} - Iftrue
, passes the request object to the verify callback. (optional, defaults to false)
Authenticate Requests
Use passport.authenticate()
, specifying the 'indieauth'
strategy, to authenticate requests. The strategy can handle both POST and GET requests.
// example authenticating a request to a route in Express
app.get('/profile', passport.authenticate('indieauth', { failureRedirect: '/login' }),
function(req, res) {
// req.user contains the authenticated user instance
return res.send('<h1>Logged in as ' + req.user.url + '</h1>');
});
You can use the strategy for both requesting an auth code from a login page, and handling the code verification on the redirect route.
// Capture the request params on POST and kick off the authorization flow
app.post('/auth', passport.authenticate('indieauth', {
failureRedirect: '/login', failureFlash: true,
}));
// put on your redirect route to handle the auth response and verification
app.get('/auth/callback', passport.authenticate('indieauth', {
successRedirect: '/profile', failureRedirect: '/login', failureFlash: true,
}));
Getting the User Profile
The strategy provides structured profile data consistent with the Portable Contacts draft spec if found when parsing the user's domain response. Note that not all possible mappings are currently implemented at this time. The full parsed JSON data is included in the _json
property. See microformats2 for the structure of this data, and h-card draft spec for standard properties.
passport.use(new IndieAuthStrategy({
clientId: 'https://example-client.com/',
redirectUri: 'https://example-client.com/auth/callback',
}, function(uid, token, profile, done) {
// Save access token for micropub or media endpoint requests
var user = {
uid: uid,
token: token,
};
if (profile.name && profile.name.formatted) {
user.name = profile.name.formatted;
}
if (profile.photos && profile.photos.length) {
user.avatarUrl = profile.photos[0].value;
}
// etc.
});
});
Using IndieAuth
See the IndieWebCamp wiki entry for IndieAuth and setup instructions to start using your own domain for web sign-in. In addition to your client id being your web application's domain name, the protocol requires the inclusion of a <link rel="redirect_uri" />
tag on your root page. (note: this is seems to be a "soft" requirement at this point).
Users may optionally specify a rel="authorization_endpoint"
on thier home page to use an authentication service of thier choosing. To make profile information available, a user will need to have an h-card in the body of thier home page.
Users may also optionally specify a rel="token_endpoint"
on thier home page to indicate the availability of generating access token on thier behalf. In order for a token to be acquired, and authorization_endpoint also needs to be configured or discoverable by the token_endpoint.
Other Usage Notes
The strategy currently uses a
_csrf
request property as thestate
parameter in authentication requests to the discovered service to prevent CSRF attacks. It is recommended to use a middleware like csurf to generate csrf tokens to embed on your login page.For allowing unauthenticated requests, specify passport-anonymous after indieauth:
passport.authenticate(['indieauth', 'anonymous']);
Even though this stategy obtains an access token when possible, it does not authenticate access tokens. Use another passport strategy like passport-http-bearer.
Related Modules
- passport-indieauth - IndieAuth authentication strategy for Passport.
- relmeauth - A rel=me auth middleware implementation in node.js. Works with any connect-type web application.
- passport - Simple, unobtrusive authentication for Node.js.
- microformat-node - Microformats parser for node.js.
Tests
$ npm install
$ npm test
Contributing
Please feel free to submit bugs and feature requests through the issues interface. I welcome pull requests, even for small things.
Tests
The test suite is located in the test/
directory. All new features are expected to have corresponding test cases. Ensure that all tests are passing by running the test command. Improvements to the test suite are welcome (I'm new), submit a pull request!
npm test
Credits
License
Copyright (c) 2016 Richard Carls