⚠️ This repo has been deprecated and code relocated! See Force for new location.
Wires up the common auth handlers, and related security concerns, for Artsy's Ezel-based apps using passport. Used internally at Artsy to DRY up authentication code.
We mave migrated this app from the module "artsy-passport" to "@artsy/passport", and called that v1.
Make sure you first mount session, body parser, and start @artsy/xapp.
app.use express.bodyParser()
app.use express.cookieParser('foobar')
app.use express.cookieSession()
artsyXapp.init -> app.listen()
Values indicate defaults.
app.use artsyPassport
CurrentUser: # The CurrentUser Backbone model
# Pass in env vars
# ----------------
FACEBOOK_ID: # Facebook app ID
FACEBOOK_SECRET: # Facebook app secret
ARTSY_ID: # Artsy client id
ARTSY_SECRET: # Artsy client secret
ARTSY_URL: # SSL Artsy url e.g. https://artsy.net
APP_URL: # Url pointing back to your app e.g. http://flare.artsy.net
SEGMENT_WRITE_KEY: # Segment write key to track signup
# Defaults you probably don't need to touch
# -----------------------------------------
# Social auth
facebookPath: '/users/auth/facebook'
facebookCallbackPath: '/users/auth/facebook/callback'
# Landing pages
loginPagePath: '/log_in'
signupPagePath: '/sign_up'
settingsPagePath: '/user/edit'
afterSignupPagePath: '/personalize'
# Misc
logoutPath: '/users/sign_out'
userKeys: [
'id', 'type', 'name', 'email', 'phone', 'lab_features',
'default_profile_id', 'has_partner_access', 'collector_level'
]
The keys are cased so it's convenient to pass in a configuration hash. A minimal setup could look like this:
app.use artsyPassport _.extend config,
CurrentUser: CurrentUser
Note: CurrentUser must be a Backbone model with typical get
and toJSON
methods.
h1 Login
pre!= error
a( href=ap.facebookPath ) Login via Facebook
form( action=ap.loginPagePath, method='POST' )
h3 Login via Email
input( name='name' )
input( name='email' )
input( name='password' )
input( type="hidden" name="_csrf" value=csrfToken )
button( type='submit' ) Login
h1 Signup
pre!= error
a( href=ap.facebookPath ) Signup via Facebook
form( action=ap.signupPagePath, method='POST' )
h3 Signup via Email
input( name='name' )
input( name='email' )
input( name='password' )
input( type="hidden" name="_csrf" value=csrfToken )
button( type='submit' ) Signup
h2 Linked Accounts
pre!= error
- providers = user.get('authentications').map(function(a) { return a.provider })
if providers.indexOf('facebook') > -1
| Connected Facebook
else
a( href=ap.facebookPath ) Connect Facebook
{ loginPagePath, signupPagePath, settingsPagePath, afterSignupPagePath } = artsyPassport.options
app.get loginPagePath, (req, res) -> res.render 'login'
app.get signupPagePath, (req, res) -> res.render 'signup'
app.get settingsPagePath, (req, res) -> res.render 'settings'
app.get afterSignupPagePath, (req, res) -> res.render 'personalize'
In your server-side templates
h1 Hello #{user.get('name')}
In your client-side code
CurrentUser = require '../models/current_user.coffee'
sd = require('sharify').data
user = new CurrentUser(sd.CURRENT_USER)
In your routers
app.get '/', (req, res) ->
res.send 'Hello ' + req.user.get('name')
These forms of user will be null if they're not logged in.
If you implement a fancier auth flow that involves client-side redirecting back, you may find this helper useful in avoiding "open redirect" attacks.
sanitizeRedirect = require 'artsy-passport/sanitize-redirect'
location.href = sanitizeRedirect "http://artsy.net%0D%0Aattacker.com/"
# Notices the url isn't pointing at artsy.net, so just redirects to /
Add a local.artsy.net
entry into your /etc/hosts
127.0.0.1 localhost
#...
127.0.0.1 local.artsy.net
Install node modules yarn
then write a ./config.js that looks something like this:
module.exports = {
FACEBOOK_ID: '',
FACEBOOK_SECRET: '',
ARTSY_ID: '',
ARTSY_SECRET: '',
ARTSY_URL: 'https://api.artsy.net',
APP_URL: 'http://local.artsy.net:4000',
// An Artsy user that's linked to Facebook
ARTSY_EMAIL: 'craig@artsy.net',
ARTSY_PASSWORD: '',
FACEBOOK_EMAIL: 'craigspaeth@gmail.com',
FACEBOOK_PASSWORD: '',
}
Then you can check the example by running yarn example
and opening localhost:4000.
The tests are a combination of integration and middleware unit tests. To run the whole suite use yarn test
.
yarn compile
yarn publish