Node.js - Passport
For Node.js application, we recommend passport, an authentication middleware for Node.js. Passport supports a comprehensive set of strategies including username/password login and social login (Facebook, Twitter, etc).
For SimpleLogin, you can use either OAuth strategy or OpenId Connect strategy. In this guide, we will use the OpenId Connect Strategy. The code along with a step-by-step guide is also available on https://github.com/simple-login/passportjs-example
Preparation
First please install passport
, passport-openidconnect
, express-session
(passport uses session to store its data)
npm install passport@^0.6.0 passport-openidconnect@0.0.2 express@^4.18.1 express-session@^1.17.3 --save
Then please store your SimpleLogin AppID and AppSecret somewhere, preferably in env
variable as recommended in the The Twelve Factors.
export CLIENT_ID={your_app_id}
export CLIENT_SECRET={your_app_secret}
Bootstrap the app:
var express = require('express');
// For Passport
var session = require('express-session');
var passport = require('passport');
var OidcStrategy = require('passport-openidconnect').Strategy;
var app = express();
// passportjs use session to store user info
app.use(session({
secret: 'my-super-secret',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, next) => {
next(null, user);
});
passport.deserializeUser((obj, next) => {
next(null, obj);
});
Config SimpleLogin OIDC Provider
Let's tell passport SimpleLogin OIDC (OpenID Connect) setting:
// config SimpleLogin OIDC (OpenID Connect) provider
passport.use('SimpleLogin', new OidcStrategy({
// SimpleLogin OIDC Settings
issuer: 'https://app.simplelogin.io',
authorizationURL: 'https://app.simplelogin.io/oauth2/authorize',
tokenURL: 'https://app.simplelogin.io/oauth2/token',
userInfoURL: 'https://app.simplelogin.io/oauth2/userinfo',
// SimpleLogin App Credential from env
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
// you might need to change the callbackURL when deploying on production
callbackURL: 'http://localhost:3000/callback',
// openid needs to be in scope
scope: 'openid'
}, (issuer, sub, profile, accessToken, refreshToken, done) => {
return done(null, profile);
}));
Login endpoint
When user clicks on Sign in with SimpleLogin, user gets redirected to the SimpleLogin authorization page. This is done using the /login
endpoint. The nice thing about passport and its OpenID Connect strategy is it also takes care of generating a random state
in the redirection URL. The state
is necessary to defend against CSRF attack.
// redirect user to authorization page
app.use('/login', passport.authenticate('SimpleLogin'));
Callback endpoint
When user approves sharing data with your app, they get redirected back to the redirect_uri
in the previous step. This route is handled by an endpoint that receives the code
and exchanges for access token
. The access token
is then used to exchange for user info. Passport once again handles all these details nicely:
// user is redirected back
app.use('/callback',
passport.authenticate('SimpleLogin', {
failureRedirect: '/error'
}),
(req, res) => {
var user= req.user._json
res.send(`
Welcome ${user.name}! <br>
Your email: ${user.email} <br>
Avatar: <img src="${user.avatar_url}">
`)
}
);
Run the App and enjoy!
let's finish by adding this to the end:
app.listen(3000, () => console.log(`App listening`))
And run the app
node app.js
Now you should be able to sign in with SimpleLogin at http://localhost:3000/login